Video to GIF for Slack: Sizes That Actually Post
By Mark Fulton · 2026-08-14 · 15 min read

Slack's help centre does not publish a GIF-specific size limit. What it publishes is a ceiling on any file you add — "You can add files up to 1GB in size" — plus a pixel rule for inline previews: an image only displays in the message if it is "smaller than 25,000 pixels on the longest side, and less than 45 million pixels total". Both read off Slack's own Add files to Slack page on 14 August 2026. So the limit you are fighting is not Slack's, it is your reader's patience and their scroll: a GIF stores every frame as a whole image with no motion compression, so the same six seconds costs about 2.4 MB at 640 px and 18 fps but about 0.36 MB at 320 px and 8 fps. Export at 480 px, 12 fps, under ten seconds, and it posts, loads and reads.
That is the short version. The longer version matters because the pages ranking for this query state three different numbers — 5 MB, 50 MB, 1 GB — and not one of them links to a Slack page to back it up. Slack's own documentation says 1 GB for files generally and never singles GIFs out. Numbers that nobody sources are numbers that were true once, somewhere, and got copied forward.
Below are the real levers, with output sizes I measured at write time rather than estimated, and the one Slack behaviour that decides whether your GIF moves at all on the other person's screen.
Why is my GIF too large for Slack?
Because GIF has no idea that your frames are related to each other.
An H.264 video spends almost all its bits describing differences: a static screen recording costs a keyframe and then near-nothing until something moves. GIF, designed in 1987 for still images, stores each frame as a complete indexed picture, at most 256 colours, compressed with LZW — a general-purpose algorithm that looks for repeated byte runs within a single image and knows nothing about the frame before it. The full mechanics are in why a GIF balloons next to the MP4 it came from. The practical consequence is that a GIF's size is close to:
frames × pixels per frame × (bytes each pixel costs after LZW)
Which gives you exactly four levers, in the order they bite:
- Clip length — linear. Ten seconds costs twice five seconds. Free to fix, and the only lever that costs you nothing visually.
- Frame rate — linear. 18 fps is 1.5× the frames of 12 fps for the same duration.
- Pixel width — quadratic, because halving the width halves the height too. 640 → 480 px is 56% of the pixels; 640 → 320 px is 25%.
- Palette and dither — the only lever that can go either way, and the one nobody explains. More on that below.
The worked example
Here is the same clip at three settings. The source is a six-second, 1280×720, 30 fps test clip I rendered with FFmpeg for this post: a code editor with a dark header bar, a light sidebar, scrolling monospaced text and a cursor moving across it — flat UI colours throughout, which is what a screen recording of an app actually looks like. Each export ran the same one-pass filter graph VidClip's converter uses (fps → scale with lanczos → palettegen with stats_mode=diff → paletteuse with a Bayer dither), with no watermark, and I read the byte counts off the resulting files.
| Setting | Frames | Output size | Measured file | Bytes per frame |
|---|---|---|---|---|
| 640 px, 18 fps | 108 | 640×360 | 2,485,006 bytes (2.37 MB) | 23,009 |
| 480 px, 12 fps | 72 | 480×270 | 1,104,484 bytes (1.05 MB) | 15,340 |
| 320 px, 8 fps | 48 | 320×180 | 376,332 bytes (0.36 MB) | 7,840 |
For reference, the source MP4 was 100,768 bytes. The 480 px GIF is roughly eleven times the size of the video it came from, at a quarter of the resolution. That is not a bad encode. That is GIF.
Two things in that table are worth more than the headline numbers.
The cuts do not multiply out cleanly. Going from row one to row two removes 44% of the pixels and 33% of the frames, so naive arithmetic predicts a 2.7× saving. The real saving was 2.25×. Look at the last column for why: bytes per pixel went up as the image got smaller — 0.100 at 640 px, 0.118 at 480 px, 0.136 at 320 px. Downscaling blends neighbouring pixels into new intermediate colours, which breaks up the long flat runs LZW was feeding on. Shrinking still wins, decisively. It just wins slightly less than the pixel count suggests, and anyone quoting you a clean percentage has not run it.
Content decides everything. This clip is flat UI colour, which is the friendly case. A recording containing a photograph, a video thumbnail, a gradient background or a dark-mode blur will land materially higher at identical settings, because every one of those things is expensive to describe in 256 colours. Treat the table as the shape of the curve, not as a promise about your file.
How many frames per second does a GIF really need?
Fewer than you think, and the answer depends on what is moving.
Frame rate is a linear multiplier on file size, which makes it the cheapest big cut available after trimming. It is also the cut people refuse to make, because "30 fps" sounds like quality. In a 480-pixel-wide loop in a chat window it mostly isn't.
- 8 fps — fine for anything that changes in discrete steps: clicking through a UI, a form validating, a dashboard updating. Continuous motion at 8 fps reads as a flipbook.
- 12 fps — the default worth keeping. Smooth enough that a cursor gliding across a screen looks like a cursor gliding, and half the frames of 24.
- 18 fps — worth the ~50% size penalty only when something moves continuously and smoothly: a scroll, a drag, an animation you are specifically demoing.
The interaction that catches people out is between frame rate and what kind of motion you recorded. A screen that sits still between clicks is nearly free at any frame rate, because consecutive frames are near-identical and compress hard. A screen that scrolls is the worst case in the format, because every pixel changes at once, every frame, and GIF has to pay full price for each. If you can demonstrate the thing without scrolling — cut, or jump — do. A cut costs one expensive frame. A three-second scroll costs thirty-six of them.
VidClip's converter exposes 8, 12 and 18 fps and widths of 320, 480 and 640 px for exactly this reason: those are the decisions that move the number, and there is no point offering a slider for the ones that don't.
What does palette optimisation change?
This is the lever the tool pages skip, and it is the one where the obvious assumption is backwards.
Every frame of a GIF indexes into a table of at most 256 colours. A naive converter maps your footage onto one fixed, generic table — an even cube through RGB space — and hides the resulting damage by dithering, scattering dots of the nearest available colours to fake the ones it lacks. That is the speckled, grainy look most people associate with GIFs. The better approach, documented in the FFmpeg filters reference, is palettegen: analyse the clip you actually have, build the 256 colours that best describe it, then map frames against that. A screen recording with a grey chrome, a white editor and four syntax-highlight colours can be described almost perfectly by a custom palette, and barely at all by a generic one.
Now the counterintuitive part. I encoded the same clip both ways, at 480 px and 12 fps:
| Palette method | Measured file |
|---|---|
| Generic fixed 256-colour table | 507,218 bytes (0.48 MB) |
| Palette generated from the clip | 1,104,484 bytes (1.05 MB) |
The good-looking one is twice the size. Dithering against a generic table produces a dense scatter of alternating pixels, and I expected that to compress badly — but it also flattens the image into a small set of repeated dot patterns that LZW handles well, and it throws away the subtle colour variation a generated palette carefully preserves. Comparing crops of the two side by side, the generic-palette version shows a visible dotted texture across the flat background and mottled, softened glyph edges on the code; the generated-palette version has a clean background and letters with crisp edges.
So palette optimisation is not a size trick. It is a fidelity trick that costs bytes, and it is worth every one of them when the content is text — which, in Slack, it usually is. If you need to buy those bytes back, take them from frame rate or width, where the loss is honest and predictable, rather than from colour, where the loss looks like a broken file.
Two smaller settings sit alongside it. Turning the dither off entirely saved about 4% here (1,064,707 bytes) and produces flat banding on any gradient. Switching palettegen from stats_mode=diff — which weights the palette toward the parts of the frame that change — to full moved the file by about 1%. Neither is where your megabytes are.
Should a screen recording be a GIF or an MP4 upload?
Honestly: in Slack, usually MP4.
A video file is just a file as far as Slack's documented limits go — the same 1 GB ceiling covers it, and Slack's help pages describe inline previews for images without publishing an equivalent rule for uploaded video, so how a given workspace and client display it is worth confirming by posting one into a DM to yourself. What is not in doubt is the size difference, and it is not marginal. I encoded the same source at the same 480-pixel width as an H.264 MP4 at CRF 23 with no audio: 59,547 bytes, against 1,104,484 for the GIF. That is 18.5× for a picture that is visibly better, because the video is not restricted to 256 colours. Google's web.dev guidance on replacing animated GIFs with video measures the same effect on real content: a 3.7 MB GIF becoming a 551 KB MP4.
There is one Slack-specific catch that pushes the decision back the other way, and no page ranking for this query mentions it. Slack lets each person turn animation off. Its help page on managing animated images and emoji documents a desktop preference called "Automatically play animations in Slack" under Preferences → Accessibility → Other display options, an iOS toggle for "Allow Animated Images" that can sync with the device's own motion settings, and an Android toggle for "Allow animated images & emoji". Slack's page does not state what the default is, and the setting is per-person, so you cannot know from your end whether your GIF is moving on someone else's screen. Anyone using the OS-level reduce-motion setting has likely turned it off deliberately.
That leads to a rule that is more useful than a size limit:
Use a GIF when the loop is the message and it works as a still if it never plays — a two-second before/after, a state change, a reaction. Also use one when the destination only accepts images: a README, an issue tracker, documentation, an email.
Use an MP4 when it is a demo with a beginning and an end, when it runs longer than about ten seconds, when it contains photographic or gradient content, or when the recipient needs playback controls — the ability to pause on the frame that matters, or replay one part without watching the loop go round again. Anything instructional is in this category.
Use a still frame when the point is one moment. It is smaller than both, it is readable to everyone regardless of their animation preference, and it can be zoomed.
One more thing worth knowing: Slack's Allow GIFs in Slack page describes an admin-controlled "Attach a GIF" setting, and is explicit that switching it off "will remove the GIF picker from the message field, but won't prevent members from uploading GIFs found elsewhere". If the GIF button has vanished from your workspace, an admin turned off the search picker. Your own uploaded file is a different path and still works.
How do you make one without uploading the clip?
Every converter in the top results for this query works the same way: you send your file to a company's server, it gets processed in a queue, and the output waits for you to download it. EZGIF, the tool most people reach for, states that uploads are deleted an hour later — which is a reasonable policy and still means a copy of your screen recording existed on someone else's disk. When the recording is a customer's dashboard, a production bug with credentials on screen, or an internal roadmap, that is a decision worth making on purpose.
VidClip's video-to-GIF converter runs FFmpeg compiled to WebAssembly inside the browser tab. Your file is read from disk into the page's memory, encoded on your own CPU, and written back to your disk. There is no upload bar because there is nothing to upload — the server only ever sent you the page. The workflow, in the order that gets the smallest good-looking file:
- Trim first. This is the largest, cheapest saving available and it changes every number downstream. Find the two to six seconds that carry the point.
- Crop or resize if the frame is mostly empty. A full 1440p desktop where the action lives in one window is mostly wasted pixels. Removing them keeps the part you care about at native sharpness instead of scaling it down with everything else.
- Set the width. 480 px is the default for a reason: readable inline in Slack on a laptop, a quarter of the bytes of 640 px worth of picture that nobody expands.
- Set the frame rate. 12 fps unless something scrolls continuously.
- Look at the output at 100% before you post it. If the point was an error message, read the error message in the exported GIF. Text is the first casualty of every setting on this list.
Free exports cap input files at 200 MB and carry a small mark in the corner of the frame. Pro — $4/mo billed as $24 per six months, or $79 once for life — removes both, and adds instant lossless trimming so step one costs no quality at all.
FAQ
What size GIF works in Slack?
Slack's own help pages do not state a GIF-specific limit for messages. The Add files to Slack page, checked 14 August 2026, says "You can add files up to 1GB in size", and adds that an image previews inline only when it is "smaller than 25,000 pixels on the longest side, and less than 45 million pixels total" — a pixel gate, not a byte gate, and one that no reasonable GIF approaches. That page states no per-plan difference for upload size, though plan differences do exist elsewhere in Slack, so check your workspace's plan page if you are near any ceiling. Practically, aim under about 2 MB: it posts instantly, loads on a phone, and is well inside anything Slack applies. Custom emoji are a completely different job with real, published limits — see below.
Why does my GIF look grainy?
Almost always the palette, not the resolution. A GIF frame can hold 256 colours, and a converter that maps your clip onto one generic table has to fake everything else by dithering — scattering dots of nearby colours to approximate the ones it doesn't have. On flat UI colours and text, that reads as a speckled haze over the background and fuzz around every letter. A converter that generates the palette from your actual footage first describes those few flat colours almost exactly. The tradeoff is real and runs the way people don't expect: in the test above the good-looking generated-palette export was twice the size of the grainy generic one. Buy the quality back from frame rate or width instead — those degrade honestly.
Do GIFs autoplay in Slack?
Not for everyone, and you cannot tell which. Slack's help page on managing animated images and emoji documents a per-person preference — "Automatically play animations in Slack" on desktop, under Preferences → Accessibility → Other display options, with equivalent toggles on iOS and Android, the iOS one able to follow the device's own motion settings. Slack's page does not say what the default is, so treat animation as likely but not guaranteed, and assume some colleagues have deliberately switched it off. The design implication: make the first frame of your GIF stand on its own. If the clip only makes sense in motion, upload an MP4, which comes with a play button that works for everybody.
Is an MP4 better than a GIF for a demo?
For a demo, yes, on every axis that matters. Encoding the same clip at the same 480-pixel width gave 59,547 bytes as an H.264 MP4 against 1,104,484 bytes as a GIF — 18.5× smaller — with better colour, because video is not capped at 256 of them. A video also arrives with playback controls, so the reader can stop on the frame that shows the bug instead of waiting for the loop to come round. A GIF earns its place when the loop is the whole message, when the destination accepts images only, or when a two-second before/after would be spoiled by a play button sitting on top of it. Those cases are real and that is when a GIF converter is the right tool — but a three-minute walkthrough should never have been a GIF.
What about Slack custom emoji?
Different job, different rules, and they are published. Slack's custom emoji page says "Square images under 128KB and with transparent backgrounds work best. Images can be in JPG, PNG, or GIF format", and that "GIFs can include up to 50 frames". A 128 KB budget across up to 50 frames is roughly 2.5 KB per frame, which is why emoji-sized GIFs have to be tiny in every dimension at once: a square around 128 px, a very low frame rate, a short loop, and a palette cut well below 256 colours. Do not size a message GIF by emoji rules or you will throw away quality you never needed to lose.
Got a recording that needs to go in a channel? Make the GIF in the browser — trim it, set the width and the frame rate, download the file. Nothing uploads, there is no queue, and the clip never leaves your machine.