Glossary

How to Post a Bluesky GIF That Keeps Moving

Taras Shynkarenko
Taras Shynkarenko
•Updated: •8 min read
How to post a Bluesky GIF that keeps movingHow to post a Bluesky GIF that keeps moving

TL;DR, Quick Answer

8 min read

The Bluesky app adds GIFs two ways. The Select GIF button searches KLIPY, which replaced Tenor in April 2026, and stores the GIF as a link card. An animated GIF file you upload goes through Bluesky's video pipeline and is saved as a video with a "gif" presentation hint. A GIF placed in an app.bsky.embed.images record is valid up to 2,000,000 bytes, but by our reading of Bluesky's image server code, the CDN's re-encoded copy keeps one frame, so it shows as a still frame. AdaptlyPost converts a post's only animated GIF to MP4 and posts it as a Bluesky video with the gif hint, so it loops. A GIF that shares a post with other images still goes out as an image.

How do GIFs work on Bluesky?

A Bluesky GIF reaches a post in one of three ways, and only two of them keep the animation: a GIF picked from the app's built-in search, an animated GIF file uploaded from your device, or a GIF file sent as a plain image by a third-party client. The first two play in the feed. The third is a valid record, but by our reading of Bluesky's code it shows as a still picture.

The difference comes from how each route stores the GIF in the AT Protocol record behind the post:

RouteRecord typeWhat viewers seeSize rule
GIF picker in the appapp.bsky.embed.external, a link to the GIF plus a thumbnailA looping GIFThumbnail blob up to 1,000,000 bytes; the GIF stays on the provider's servers
Uploaded animated GIF fileapp.bsky.embed.video with presentation: "gif"A muted looping video styled as a GIFVideo blob up to 300,000,000 bytes in the lexicon
GIF sent as an imageapp.bsky.embed.imagesA still image, by our reading of Bluesky's codeImage blob up to 2,000,000 bytes

The size rules come from the maxSize values in Bluesky's lexicon files on GitHub. The rest of this page walks through each route.

Where does Bluesky's GIF picker get its GIFs?

Bluesky's GIF picker searches KLIPY, a third-party GIF library that replaced Tenor in version 1.121.0 of the app, released on April 22, 2026. The release notes list the change as "Migrate from Tenor to KLIPY," and the pull request describes it as "basically a 1:1 swap from tenor to KLIPY." The search box in the picker reads "Search KLIPY."

To add a GIF from the picker:

  1. Open the post composer in the Bluesky app.
  2. Tap the GIF button, labelled "Select GIF" for screen readers.
  3. Search KLIPY or pick from the featured GIFs.
  4. Add alt text for the GIF if you want your own description.
  5. Write the post text and publish.

The picker does not upload the GIF to your account. The app builds an app.bsky.embed.external record that points at the GIF's address on KLIPY's servers, uploads a thumbnail blob, and stores the alt text in the link's description with an "Alt: " prefix. If you skip alt text, the app writes "ALT: " plus KLIPY's own description of the GIF. Bluesky's code marks KLIPY and Tenor as sources that "are proxied through our CDN and do not leak any user data," so these GIFs play without the external media warning that other embeds show.

A person scrolling through a social feed on a phone, the moment an uploaded animated GIF either loops or shows up as a still frame.

What happens when you upload a GIF file to Bluesky?

The Bluesky app checks whether an uploaded GIF file is animated, and sends an animated one through its video pipeline instead of posting it as an image. Pull request 9814, shipped in version 1.116.0 in February 2026, describes the rule: the app treats a image/gif file "as a video if it has multiple frames," and leaves a single-frame GIF as an ordinary image.

The result is saved as an app.bsky.embed.video record, which the lexicon defines as "The mp4 video file," with a presentation field set to gif. The lexicon calls that field "A hint to the client about how to present the video." Pull request 9809, "Make GIFs look like GIFs," explains what the hint does in the app: it "simplifies" the video controls "to match other gifs" and mutes the clip.

A few rules apply to GIF uploads in the app:

  • You can attach one GIF per post. A second one triggers the message "You can only select one GIF at a time."
  • The app skips its own compression step for GIFs, with a code comment noting that "this compression library doesn't support gifs." Bluesky's servers accept or reject the file.
  • GIF uploads work on the web too, added in version 1.95.0 in November 2024, where they were "processed as video" from the start.

What does the AT Protocol image embed do with a GIF?

The app.bsky.embed.images lexicon accepts a GIF blob, because its image field takes "accept": ["image/*"] with a maxSize of 2,000,000 bytes. The field description reads "The raw image file. May be up to 2 MB, formerly limited to 1 MB." Bluesky raised the cap from 1,000,000 bytes in an atproto commit dated April 8, 2026, titled "Increase max image upload size to 2mb from 1mb." Each post holds up to four images. Why the Bluesky image size limit is 2,000,000 bytes explains the byte count and how it differs from 2 MiB.

A valid record does not mean an animated one. The AppView returns thumb and fullsize URLs on Bluesky's image CDN, and the lexicon says the full-size URL "May or may not be the exact original blob." The image server code in the atproto repository re-encodes each image to JPEG or WebP with the sharp library, and it does not turn on sharp's animation option. Bluesky does not document what happens to an animated GIF here. Our reading of that code is that only the first frame makes it through, so a GIF sent as an image embed shows as a still picture.

The Bluesky app itself routes animated GIF files to video. A third-party client or API script that uploads a GIF with com.atproto.repo.uploadBlob and places it in an image embed gets a still frame, by the same reading of the code. To keep the motion, convert the GIF to MP4 and post it as a video, with presentation set to gif if your client writes that field.

How big can a Bluesky GIF be?

The size limit for a Bluesky GIF depends on the route, because each record type sets its own maxSize in the lexicon. A GIF picked from KLIPY stays on KLIPY's servers, so only its thumbnail counts, and the app.bsky.embed.external lexicon caps that thumbnail at 1,000,000 bytes. A GIF sent as an image embed can be up to 2,000,000 bytes. An uploaded animated GIF becomes a video, and the app.bsky.embed.video lexicon allows a video blob up to 300,000,000 bytes, described as "May be up to 300mb, formerly limited to 100mb."

The video lexicon number is the protocol ceiling, not a promise that Bluesky's video service accepts any GIF up to that size. Bluesky's 2024 pull request that added web GIF uploads noted that the app could not check a GIF's length before upload and left Bluesky's server to reject GIFs that break the video rules. Keep GIFs short and small: three ways to create a custom GIF file covers frame rate, color and size settings that shrink a file.

AdaptlyPost
AdaptlyPost

Start Your 7-Day Free Trial

All-platform analytics

Social Inbox

AI-powered assistant

A video editing timeline on a laptop, standing in for converting a GIF to an MP4 so the loop keeps moving when posted.

What does AdaptlyPost do with a Bluesky GIF?

AdaptlyPost posts a Bluesky GIF the way the Bluesky app does when the GIF is the only media in the post and has more than one frame: it converts the file to an MP4 and posts it as a video, so the loop keeps moving. The steps are:

  1. AdaptlyPost downloads the GIF and counts its frames.
  2. It converts an animated GIF to an H.264 MP4 with no audio track.
  3. It uploads the MP4 through Bluesky's video service and waits for processing to finish.
  4. It creates an app.bsky.embed.video record with presentation set to gif, the alt text you wrote, and the GIF's width and height as the aspect ratio.

Because the GIF goes out as a video, AdaptlyPost checks it against its Bluesky video size limit rather than the image limit, and it does not crop, compress or convert it to JPEG first.

Other GIFs go out as images. A single-frame GIF, or a GIF that shares the post with other images, is uploaded with com.atproto.repo.uploadBlob and attached to an app.bsky.embed.images record, up to four images per post. By our reading of Bluesky's image code, such a GIF shows as a still frame. When an image in that kind of post breaks one of AdaptlyPost's Bluesky rules, AdaptlyPost makes a copy:

  • The file is over AdaptlyPost's Bluesky image size limit.
  • The image falls outside the 1:3 to 3:1 shape range AdaptlyPost checks for Bluesky.
  • You picked a fixed shape in the composer's "Image shape" option (Square 1:1, Portrait 4:5, Vertical 9:16 or Landscape 1.91:1) and the GIF is a different shape.

The copy is compressed, scaled down or reframed, cropped from the center by default or fitted on a blurred background, and the adaptation code writes it as a JPEG, a format that holds one frame.

If the conversion or the video upload fails, AdaptlyPost falls back to posting the GIF as an image, so the post still goes out, as a still frame. The Bluesky post scheduler queues posts, image posts with alt text, link cards and videos, and how to schedule Bluesky posts covers the steps. The public API upload endpoint accepts image/jpeg, image/png, image/webp, video/mp4 and video/quicktime; the composer also accepts GIF files.

How AdaptlyPost posts a Bluesky GIF
One animated GIF
Converted to MP4
Bluesky video service
app.bsky.embed.video, presentation gif
A GIF that is the post's only media loops; a GIF posted next to other images goes out as an image.

Frequently asked questions

Can you post GIFs on Bluesky?

Yes. In the Bluesky app, tap the GIF button in the composer to search KLIPY, or attach an animated GIF file from your device. Picker GIFs are saved as link embeds and uploaded GIF files as videos, and both loop in the feed.

Does Bluesky still use Tenor for GIFs?

No. Version 1.121.0 of the Bluesky app, released on April 22, 2026, switched the GIF picker from Tenor to KLIPY. The picker's search box now reads "Search KLIPY," and older posts with Tenor GIFs still display.

Why does my GIF show as a still image on Bluesky?

Bluesky does not document this, but by our reading of its open-source image server, a GIF posted as an image embed is served as a re-encoded JPEG or WebP copy that keeps only the first frame. The Bluesky app sends animated GIF files through its video pipeline instead. Third-party tools that post GIFs as images produce a still frame. AdaptlyPost posts a lone animated GIF as a video, so it loops.

What is the Bluesky GIF size limit?

The limit depends on the route. A GIF in an image embed can be up to 2,000,000 bytes, a picker GIF's thumbnail up to 1,000,000 bytes, and an uploaded GIF becomes a video under the 300,000,000-byte video blob cap. The image cap was 1,000,000 bytes until April 2026.

Can I add alt text to a Bluesky GIF?

Yes. The app lets you add your own alt text to a picker GIF and stores it in the link description with an "Alt: " prefix. Without it, the app uses KLIPY's description of the GIF. Uploaded GIF videos and image embeds have their own alt field.

Can AdaptlyPost post an animated GIF to Bluesky?

Yes, when the GIF is the only media in the post. AdaptlyPost converts it to an MP4, uploads it through Bluesky's video service and posts it with the gif presentation hint and your alt text, so it loops in the feed. A GIF posted next to other images goes out as an image and, by our reading of Bluesky's image code, shows as a still frame.

What is KLIPY on Bluesky?

KLIPY is the third-party GIF library that Bluesky's GIF picker searches. It replaced Tenor in version 1.121.0 of the app, released on April 22, 2026. A picker GIF stays on KLIPY's servers, and the app uploads only a thumbnail.

Can I add more than one GIF to a Bluesky post?

The app allows one GIF per post. A second one triggers the message "You can only select one GIF at a time." An image embed holds up to four images, but by our reading of Bluesky's code a GIF placed there shows as a still frame.

How do I keep a GIF moving when I post it to Bluesky?

Post the GIF on its own. In the Bluesky app, an attached animated GIF file goes through the video pipeline and loops. AdaptlyPost does the same for a post whose only media is an animated GIF and posts it as app.bsky.embed.video with the gif hint. A GIF mixed with other images goes out as an image.

AdaptlyPost
AdaptlyPost

Start Your 7-Day Free Trial

All-platform analytics

Social Inbox

AI-powered assistant

Does the Bluesky GIF picker show an external media warning?

GIFs from KLIPY and Tenor play without the warning that other embeds show. Bluesky's code marks both as sources that "are proxied through our CDN and do not leak any user data."

Was This Article Helpful?

Let us know what you think!

See us more often in Google

One click marks AdaptlyPost as a preferred source, so our articles sit higher in your Top Stories, AI Mode, and AI Overviews.

Before you go...

AdaptlyPost

AdaptlyPost

Schedule your content across all platforms

Manage all your social media accounts in one place with AdaptlyPost.

All-platform analytics

Social Inbox

AI-powered assistant

Related Glossary Terms

Related Articles