Glosario

Por qué el límite de tamaño de imagen de Bluesky es de 2,000,000 bytes

Taras Shynkarenko
Taras Shynkarenko
Actualizado: 8 min de lectura
Por qué el límite de tamaño de imagen de Bluesky es de 2,000,000 bytesPor qué el límite de tamaño de imagen de Bluesky es de 2,000,000 bytes

TL;DR, Respuesta Rápida

8 min de lectura

Bluesky limita la imagen de un post a 2,000,000 bytes, una cifra escrita como maxSize en el lexicon app.bsky.embed.images, el esquema del protocolo. Son dos millones de bytes, no 2 MiB, así que una imagen que tu gestor de archivos llama 1.95 MB ya se pasa. Avatares, banners y miniaturas de tarjetas de enlace se quedan en la mitad, 1,000,000 bytes. La app de Bluesky nunca envía tu archivo original: recodifica cada imagen de post a JPEG con 4,000 píxeles como máximo y busca una calidad que quepa bajo el tope.

¿Cuál es el límite de tamaño de imagen de Bluesky?

Cada imagen adjunta a un post de Bluesky está topada en 2,000,000 bytes, así que el límite de tamaño de imagen de Bluesky son dos millones de bytes y no los 2 MiB que la mayoría de gestores de archivos quiere decir cuando escribe "2 MB". La cifra no está enterrada en un artículo de ayuda. Está en el esquema del protocolo, en app.bsky.embed.images, como un campo llamado maxSize en el blob de la imagen:

"image": {
  "type": "blob",
  "description": "The raw image file. May be up to 2 MB, formerly limited to 1 MB.",
  "accept": ["image/*"],
  "maxSize": 2000000
}

Dos millones de bytes son 1.907 MiB. Un JPEG exportado que el Finder de macOS reporta como "1.9 MB" pesa unos 1,992,294 bytes y pasa por los pelos; uno que reporta como "2 MB" pesa 2,097,152 bytes y no pasa. En esa brecha de 97,152 bytes vive casi toda la confusión sobre este límite.

La propia redacción del lexicon conserva la historia. Dice que el blob "May be up to 2 MB, formerly limited to 1 MB", y por eso tantas guías de tamaños de terceros siguen publicando 1 MB. Tenían razón hace dos años y nadie volvió a editarlas.

¿Qué subida de Bluesky recibe qué límite?

Bluesky no tiene un único límite de imagen. Tiene seis topes de blob declarados en seis lexicons, y se contradicen entre sí a propósito.

LexiconQué contienemaxSizeaccept
app.bsky.embed.imagesImágenes de post, hasta 42000000image/*
app.bsky.embed.galleryElementos de galería2000000image/*
app.bsky.embed.externalMiniatura de tarjeta de enlace1000000image/*
app.bsky.actor.profileAvatar1000000image/png, image/jpeg
app.bsky.actor.profileBanner1000000image/png, image/jpeg
app.bsky.embed.videoArchivo de vídeo300000000video/mp4

Dos cosas de esa tabla pillan a la gente. Los avatares y banners están topados en la mitad de una imagen de post, y rechazan todo lo que no sea PNG o JPEG, así que un avatar WebP que sube sin problema como imagen de post queda rechazado en tu perfil. Y el blob de vídeo llega a 300,000,000 bytes, con su propia descripción anotando que antes estaba "formerly limited to 100mb", el mismo patrón que el tope de imagen.

El lexicon más nuevo, app.bsky.embed.gallery, permite un maxLength de 20 elementos, pero su propio comentario de esquema pide a los clientes que se contengan: "The schema-level maxLength of 20 is a future-proof ceiling. Clients should currently enforce a soft limit of 10 items in authoring UIs." El embed más antiguo, app.bsky.embed.images, se queda en 4.

Un teléfono muestra una foto lista para compartir, una imagen del paso de compresión antes de subirla.

¿Qué le hace la app de Bluesky a tu imagen antes de subirla?

El cliente oficial nunca envía tu archivo original. Antes de llamar a uploadBlob, el compositor ejecuta compressImage contra una configuración en src/lib/constants.ts:

export const IMAGE_SIZE_CONFIG_POSTS = {
  maxDimension: 4000,
  maxSize: 2000000,
};

Esa función no comprueba si tu archivo ya es lo bastante pequeño. Recodifica sin condiciones, siempre a JPEG, y hace una búsqueda binaria de un nivel de calidad que aterrice por debajo de 2,000,000 bytes. Empieza en calidad 51, sube si el resultado cabe y baja si no cabe, y se detiene cuando la ventana de búsqueda se cierra.

Cuando una imagen se resiste a la compresión, el código se niega a seguir bajando la calidad. El comentario del código fuente deletrea la regla: "binary search will check 51, 26, 13(rounded). We don't want to go below 25, so if we've halved to 13, reset the loop and reduce the image dimensions instead." Cada reinicio multiplica la dimensión de trabajo por 0.8, lo que lleva 4000 a 3200, luego 2560, luego 2048 y luego unos 1638 píxeles. Cuatro reinicios son el techo, y pasado eso la subida falla con Unable to compress image.

De que toda imagen de post se recodifique a JPEG se siguen tres consecuencias. La transparencia desaparece, porque JPEG no tiene canal alfa, así que un logo PNG sobre fondo transparente llega con un fondo sólido. El texto nítido y el color plano recogen artefactos de anillo que ese mismo archivo no mostraría en una plataforma que deja pasar el PNG. Y tus cuidados ajustes de exportación se tiran, porque el cliente elige su propio número de calidad al margen de lo que tú elegiste. Esa misma recodificación también rellena el campo aspectRatio a partir de la salida comprimida y no de tu original, y ese campo son dos enteros con un mínimo de 1, no un float.

Cómo escala el compresor cuando la calidad sola no basta
1
Empieza en calidad 51. Comprueba si el JPEG queda por debajo de 2.000.000 bytes.
2
Sigue buscando. Si el archivo aún pesa demasiado, baja a calidad 26 y luego a 13 (redondeado).
3
No baja la calidad de 25. En su lugar reinicia la búsqueda y reduce las dimensiones multiplicando por 0,8.
4
Reduce la dimensión paso a paso. 4000 píxeles pasan a 3200, luego 2560, luego 2048, luego unos 1638.
5
Se rinde tras cuatro reinicios. Pasado ese límite, la subida falla con "Unable to compress image".
La app nunca envía tu archivo original, lo recodifica a JPEG y recorre esta escalera antes de fallar.

¿Por qué una imagen demasiado grande sube igual a veces?

Porque la subida del blob y la escritura del registro son dos peticiones distintas con dos límites distintos, y solo la segunda lee el lexicon.

El endpoint com.atproto.repo.uploadBlob aplica el tope propio del servidor, que en el PDS de referencia vale por defecto 5 * 1024 * 1024, o sea 5,242,880 bytes, configurable con la variable de entorno PDS_BLOB_UPLOAD_LIMIT. Si lo superas, el stream aborta con Max size of 5242880 bytes exceeded. Si te quedas por debajo, el blob se acepta incluso con 4 MB, muy por encima de los 2,000,000 del lexicon.

El lexicon dice dónde ocurre la comprobación de verdad. Su descripción reza: "The blob will be deleted if it is not referenced within a time window (eg, minutes). Blob restrictions (mimetype, size, etc) are enforced when the reference is created." Así que una imagen de 4 MB sube con éxito, se queda en almacenamiento temporal, falla la validación cuando intentas adjuntarla a un post y se recoge como basura minutos después. Quien publica con un cliente propio en lugar de la app oficial choca con este orden y lee la subida correcta como luz verde.

Ese mismo endpoint carga con un límite de 1,000 puntos al día, lo que pone un techo duro a cuántas imágenes puede empujar una cuenta en 24 horas. Es uno de varios topes que conviene leer junto a los límites de tasa que el AT Protocol aplica a las escrituras si publicas con calendario.

AdaptlyPost
AdaptlyPost

Prueba gratis de 7 días

Analíticas multiplataforma

Bandeja Social

Asistente con IA

Un fotógrafo revisa los ajustes de exportación en la pantalla de una cámara, relevante para elegir las dimensiones correctas antes de publicar.

¿Qué dimensiones deberías exportar para Bluesky?

Nada en el lexicon restringe las dimensiones en píxeles. No hay ancho mínimo, ni alto máximo, ni relación de aspecto obligatoria en ninguna parte de app.bsky.embed.images. La única cifra de dimensión que existe es el maxDimension: 4000 del propio cliente, y eso es un disparador de redimensión, no un rechazo.

El consejo práctico que sale de ahí es corto. Exporta a 2,000 píxeles en el lado largo o menos, para que el cliente no tenga motivo de redimensionar ni de bajar la calidad a lo bruto. Usa JPEG tú mismo, ya que la app va a convertir a JPEG de todas formas y tu codificador está mejor afinado que una búsqueda binaria de calidad. Mantén el archivo por debajo de 1.8 MB para dejar margen a la recodificación. Si necesitas transparencia o texto nítido, aplana la imagen sobre el color de fondo que quieras antes de subirla, porque la alternativa es dejar que el codificador JPEG elija por ti.

El texto alternativo no tiene tope declarado en el lexicon. La app oficial aplica su propio MAX_ALT_TEXT = 2000, que es una regla de cliente y no del protocolo, así que otros clientes fijan la suya. Eso refleja cómo Bluesky maneja enlaces y menciones, donde los offsets de bytes en los facets de un post son asunto del protocolo y el renderizado es asunto del cliente.

Si comparas especificaciones entre redes antes de montar un preset de exportación, la aritmética de las dimensiones de imagen de Instagram funciona distinto, porque Meta redimensiona en el servidor en lugar de hacer que el cliente lo haga. Y si preparas imágenes con antelación, el paso de compresión forma parte de programar posts en Bluesky, lo ejecutes tú o lo ejecute un cliente.

Preguntas frecuentes

¿El límite de imagen de Bluesky es 1 MB o 2 MB?

Son 2,000,000 bytes. La cifra de 1 MB era correcta antes de que subieran el tope, y el lexicon todavía registra el cambio en su propia descripción: "May be up to 2 MB, formerly limited to 1 MB." Las guías que publican 1 MB no se han actualizado desde entonces.

¿Cuántas imágenes caben en un post de Bluesky?

Cuatro, fijadas por "maxLength": 4 en el array de imágenes de app.bsky.embed.images. El lexicon más nuevo, app.bsky.embed.gallery, sube el techo de esquema a 20 mientras instruye a los clientes a aplicar un límite blando de 10.

¿Bluesky acepta PNG y WebP?

El blob de imagen de post declara "accept": ["image/*"], así que cualquier tipo MIME de imagen pasa la validación del protocolo. La app oficial convierte todo a JPEG antes de subirlo, así que un PNG que envías llega como JPEG. Los avatares y banners son más estrictos y solo aceptan image/png e image/jpeg.

¿Cuál es el límite de tamaño de avatar y banner en Bluesky?

Ambos son 1000000 bytes en app.bsky.actor.profile, la mitad del tope de imagen de post. Los avatares de generadores de feed y de listas en app.bsky.feed.generator y app.bsky.graph.list usan esa misma cifra de 1,000,000.

¿Por qué mi imagen subió bien pero mi post falló?

El endpoint de subida comprueba el límite de blob del servidor, que vale por defecto 5,242,880 bytes, y el tope de 2,000,000 del lexicon se comprueba más tarde, cuando un registro referencia el blob. Una imagen entre esas dos cifras sube y luego falla al publicar.

¿Bluesky comprime las imágenes después de subirlas?

La app comprime antes de subir, no después. La App View sirve luego derivados redimensionados desde su CDN para miniaturas y vistas a tamaño completo, y el lexicon anota que el archivo servido "May or may not be the exact original blob". El blob guardado en tu repositorio es lo que el cliente envió.

¿Bluesky comprime una imagen que ya pesa menos de 2.000.000 bytes?

El compositor de Bluesky ejecuta compressImage en cada imagen de post sin importar su tamaño de partida, y la recodifica a JPEG antes de iniciar la búsqueda de calidad. La función no comprueba el tamaño del archivo antes de empezar, así que incluso una exportación ya bien ajustada recibe una calidad JPEG nueva elegida por la app.

¿Por qué mi PNG transparente pierde el fondo al publicarlo en Bluesky?

El JPEG no tiene canal alfa, y la app de Bluesky convierte cada imagen de post a JPEG antes de subirla, así que el fondo transparente de un PNG queda relleno con un color sólido. Ocurre incluso si tu archivo original se veía bien, porque compressImage recodifica todas las imágenes sin excepción.

¿Bluesky conserva la relación de aspecto de mi archivo original?

La app rellena el campo aspectRatio a partir de la salida JPEG ya comprimida, no de tu archivo original, porque la relación se calcula después del redimensionado y la búsqueda de calidad. Ese campo guarda dos números enteros con un mínimo de 1, no una proporción decimal.

¿Existe un límite de caracteres para el texto alternativo en Bluesky?

El lexicón app.bsky.embed.images no fija ningún tope para el texto alternativo. La app oficial de Bluesky aplica su propia regla de cliente, MAX_ALT_TEXT = 2000, que es una decisión de la app y no un límite del protocolo, por lo que otros clientes pueden fijar el suyo.

AdaptlyPost
AdaptlyPost

Prueba gratis de 7 días

Analíticas multiplataforma

Bandeja Social

Asistente con IA

¿Te resultó útil este artículo?

¡Cuéntanos qué te parece!

Vernos más en Google

Un clic marca AdaptlyPost como fuente preferida y nuestros artículos aparecen más arriba en tus Noticias destacadas, el modo IA y los resúmenes con IA.

Antes de irte...

AdaptlyPost

AdaptlyPost

Programa tu contenido en todas las plataformas

Gestiona todas tus cuentas de redes sociales en un solo lugar con AdaptlyPost.

Analíticas multiplataforma

Bandeja Social

Asistente con IA

Términos relacionados del glosario

Artículos Relacionados