1
0
mirror of https://codeberg.org/fediverse/fep.git synced 2026-08-05 11:46:04 +00:00

FEP 1a11: Send Announces Containing Many Activities (#806)

Reviewed-on: https://codeberg.org/fediverse/fep/pulls/806
Co-authored-by: rimu <rimu@rimu.geek.nz>
Co-committed-by: rimu <rimu@rimu.geek.nz>
This commit is contained in:
rimu
2026-04-01 17:08:11 +02:00
committed by silverpill
parent 3aa84ce0c2
commit 4c1ff97e96
+208
View File
@@ -0,0 +1,208 @@
---
slug: "1a11"
authors: Rimu Atkinson <contact@piefed.social>
status: DRAFT
dateReceived: 2026-04-01
discussionsTo: https://socialhub.activitypub.rocks/t/fep-1a11-send-announces-containing-many-activities/8629
---
# FEP-1a11: Send Announces Containing Many Activities
## Summary
This proposal describes a mechanism for sending multiple activities in a single POST. The core idea is to extend FEP 1b12 slightly by changing the `object` property on `Announce` activities from an object to a list/array of objects.
## Motivation
Currently, ActivityPub involves sending a HTTP POST request to followers whenever something notable happens. As a user
can do a great number of notable things (posting content, liking content, following others) each minute and there can
be thousands of instances to send to, a great many POST requests can be sent in a short amount of time.
For example if 5 people cast 20 votes and there are 500 instances, the instance hosting the community containing the
posts being voted on must send 5 * 20 * 500 = 50,000 HTTP POSTs.
Each POST involves overhead and uses resources at both ends while it occurs. To reduce this overhead and resource use,
this proposal describes a mechanism for sending multiple activities in a single POST.
Benefits include: decreased network traffic, higher efficiency, greater scalability, lowered carbon emissions and lower
server costs.
## Requirements
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this specification are to be interpreted as described in [RFC-2119].
For the purposes of this document, a "Origin Server" is the location where a user is logged in, and that sends the Actor's Activity. A "Remote Server" is another location on the Internet that will receive those Activities.
## Proposal
The majority of FEP 1b12-based ActivityPub traffic involves the transfer of an `Announce` with a up/down vote in it. This FEP only addresses those activities - all other traffic is processed in the usual way.
Origin Servers SHOULD continue to send individual POSTs with a single Activity in them, just as they do now. For votes,
which are not especially time-sensitive, they MAY instead keep the Activity unsent in a queue.
Origin Servers SHOULD include metadata with each queued Activity recording the community it is being sent from and the
instance it is destined for.
Once an implementation-specific threshold is reached (e.g. a certain amount of time has passed or a queue has grown
to a certain size) the Activities from each community will be batched together under one `Announce` (per community)
and that batch federated to each destination instance.
A batch of Activities MUST be comprised of an `Announce` that has an `object` attribute that is an `OrderedCollection`
of `Like`, `Dislike`, `Undo(Like)` or `Undo(Dislike)` activities.
Remote Servers SHOULD process the Activities' object property serially in the order provided.
The batch MUST be [HTTP Signed](https://docs.joinmastodon.org/spec/security/#http) by a [`Group`](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-application) actor, the community that generated the batch, which SHOULD be find-able using WebFinger. The signature SHOULD include the date the signing took place, to make replay attacks less likely. This method of signing is widely used on the Fediverse already.
Remote Servers MAY use HTTP Signature verification to ensure the integrity of the received Activity.
### POST Example
#### Existing old-style POSTs
```
POST server.tld/inbox
Signature: a69F3mfddd99dGjmvjdjjs81e12jn121Gkm1
Digest: asdfasdfasdf
{
"actor": "https://lemmy.world/c/nostupidquestions",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"id": "https://lemmy.world/activities/like/aa6d9456-0960-4b9d15-561d1cef2991",
"actor": "https://lemmy.world/u/SpaceNo",
"object": "https://kbin.social/m/nostupidquestions@lemmy.world/t/433370/-/comment/2965",
"type": "Like",
"audience": "https://lemmy.world/c/nostupidquestions"
},
"cc": [
"https://lemmy.world/c/nostupidquestions/followers"
],
"type": "Announce",
"id": "https://lemmy.world/activities/announce/e49d182c-db32-4a10-bb-c57de890cd9e",
"@context": [
...
],
}
POST server.tld/inbox
Signature: b69F3mfddd99dGjmvjdjjs81e12jn121Gkm1
Digest: asdfasdfasdf
{
"actor": "https://lemmy.world/c/nostupidquestions",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"id": "https://lemmy.world/activities/like/aa6d9456-094bf0-9d15-561d1cef299e",
"actor": "https://lemmy.world/u/Peter",
"object": "https://kbin.social/m/nostupidquestions@lemmy.world/t/433370/-/comment/2965",
"type": "Like",
"audience": "https://lemmy.world/c/nostupidquestions"
},
"cc": [
"https://lemmy.world/c/nostupidquestions/followers"
],
"type": "Announce",
"id": "https://lemmy.world/activities/announce/e49d182c-db32-4a10-bb-c57de890cd9e",
"@context": [
...
],
}
POST server.tld/inbox
Signature: c69F3mfddd99dGjmvjdjjs81e12jn121Gkm1
Digest: asdfasdfasdf
{
"actor": "https://lemmy.world/c/nostupidquestions",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"id": "https://lemmy.world/activities/like/aa6d9456-0960-4bf0-9d15-56cef2994",
"actor": "https://lemmy.world/u/Rimu",
"object": "https://kbin.social/m/nostupidquestions@lemmy.world/t/433370/-/comment/2965",
"type": "Like",
"audience": "https://lemmy.world/c/nostupidquestions"
},
"cc": [
"https://lemmy.world/c/nostupidquestions/followers"
],
"type": "Announce",
"id": "https://lemmy.world/activities/announce/e49d182c-db32-4a10-bb-c57de890cd9e",
"@context": [
...
],
}
```
#### New and improved fep-4248-style POST
```
POST server.tld/inbox
Signature: asdfasdfasdf
Digest: asdfasdfasdf
{
"actor": "https://lemmy.world/c/nostupidquestions",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"type": "OrderedCollection",
"id": "https://lemmy.world/activities/abcd9456-0960-4b9d15-561d1cef2991",
"totalItems": 3,
"orderedItems": [
{
"id": "https://lemmy.world/activities/like/aa6d9456-0960-4b9d15-561d1cef2991",
"actor": "https://lemmy.world/u/SpaceNo",
"object": "https://kbin.social/m/nostupidquestions@lemmy.world/t/433370/-/comment/2965",
"type": "Like",
"audience": "https://lemmy.world/c/nostupidquestions"
},
{
"id": "https://lemmy.world/activities/like/aa6d9456-094bf0-9d15-561d1cef299e",
"actor": "https://lemmy.world/u/Peter",
"object": "https://kbin.social/m/nostupidquestions@lemmy.world/t/433370/-/comment/2965",
"type": "Like",
"audience": "https://lemmy.world/c/nostupidquestions"
},
{
"id": "https://lemmy.world/activities/like/aa6d9456-0960-4bf0-9d15-56cef2994",
"actor": "https://lemmy.world/u/Rimu",
"object": "https://kbin.social/m/nostupidquestions@lemmy.world/t/433370/-/comment/2965",
"type": "Like",
"audience": "https://lemmy.world/c/nostupidquestions"
}
],
}
"cc": [
"https://lemmy.world/c/nostupidquestions/followers"
],
"type": "Announce",
"id": "https://lemmy.world/activities/announce/e49d182c-db32-4a10-bb-c57de890cd9e",
"@context": [
...
],
}
```
## References
- Christine Lemmer Webber, Jessica Tallon, [ActivityPub][ActivityPub], 2018
[ActivityPub]: https://www.w3.org/TR/activitypub/
[c390]: https://codeberg.org/fediverse/fep/src/branch/main/fep/c390/fep-c390.md
[RFC-2119]: https://www.rfc-editor.org/rfc/rfc2119
## Copyright
CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
To the extent possible under law, the authors of this Fediverse Enhancement Proposal have waived all copyright and related or neighboring rights to this work.