Count BlueSky post bytes before payload errors happen
Measure exact UTF-8 text bytes, 300-character limits, tag limits, sample facet JSON, image reference pointers, and draft record JSON size before moving approved posts into ONYX scheduling.
Limit checked: 3.0 KB
Limit checked: 300 bytes
Limit checked: 5.0 KB
Limit checked: 1.00 MB
Payload checks
- Draft looks comfortably inside the checked text, tag, image-count, and JSON payload limits.
Draft post record
{
"$type": "app.bsky.feed.post",
"text": "Launching a new BlueSky workflow guide today. It covers payload size, facets, image pointers, and how to keep scheduled posts safely under protocol limits.",
"createdAt": "2026-06-21T22:26:16.929Z",
"facets": [
{
"index": {
"byteStart": 16,
"byteEnd": 23
},
"features": [
{
"$type": "app.bsky.richtext.facet#tag",
"tag": "BlueSky"
}
]
}
],
"tags": [
"BlueSky",
"ATProtocol",
"CreatorTools"
],
"embed": {
"$type": "app.bsky.embed.images",
"images": [
{
"alt": "Scheduled image 1",
"image": {
"$type": "blob",
"ref": {
"$link": "bafkreiexampleimageblob1"
},
"mimeType": "image/jpeg",
"size": 850000
},
"aspectRatio": {
"width": 1200,
"height": 800
}
}
]
}
}Text limits are not just characters
The post lexicon limits text to 300 graphemes and 3000 UTF-8 bytes. Emoji and CJK text can use more bytes than plain ASCII.
Media is referenced
Images and videos are uploaded as blobs and referenced from the record. The file bytes are not base64-inline post text.
ONYX handles the routine checks
Use this tool for diagnostics. For everyday work, ONYX packages approved BlueSky posts through the scheduler instead of making creators hand-build records.
From byte checks to a cleaner publishing queue
Payload limits matter most when posts contain complex facets, tags, references, and media pointers. ONYX keeps that work inside a reviewed scheduling flow so approved posts are tested before they enter the active queue.
Developer teams should also plan for navigating transactional synchronization mechanics and read-after-write consistency delays after a record has been written but before every AppView response has refreshed.