emptygif
Language: English

The smallest transparent GIF is 43 bytes.

This is all of it. Pick any byte to see what it does, then copy the file, download it, hotlink it, or serve it from your own code.

The 43-byte GIF, enlarged: one transparent pixel
0000
0010
0020
Download 1×1.gif

R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==

What every byte does

A GIF is a sequence of blocks. This one has seven, and every colour on this page belongs to one of them. Select a byte or a block to read it. Numbers are stored little-endian: the low byte comes first, so 01 00 means 1.

BytesFieldMeaning
Header Tells the decoder this is a GIF and which version of the format to expect.
47 49 46SignatureThe ASCII letters “GIF”. Every GIF file starts with them.
38 39 61Version“89a”. 89a is needed for transparency; 87a has no graphic control extension.
Logical screen descriptor The size of the canvas and how its colour table is set up.
01 00Canvas width1 px.
01 00Canvas height1 px.
80Packed flagsFour settings squeezed into one byte. The top bit says a global colour table follows; the last three bits give its size.
00Background colour indexPalette entry 0. Browsers ignore it and show what is behind the image.
00Pixel aspect ratio0 means square pixels, with no correction.
Global colour table The palette. Pixels store an index into this list instead of a colour.
FF FF FFPalette entryRed, green and blue, one byte each: #ffffff. Two entries is the smallest table a GIF can have.
00 00 00Palette entryRed, green and blue, one byte each: #000000. Two entries is the smallest table a GIF can have.
Graphic control extension Optional block added in GIF89a. Here it makes palette entry 0 transparent.
21Extension introducer0x21 (“!”) announces an extension block.
F9Graphic control label0xF9 says this extension is a graphic control extension.
04Block size4 bytes of settings follow.
01Packed flagsThe lowest bit is the transparency flag. It is on, so the transparent index below is used.
00 00Delay0 hundredths of a second. It only matters for animations.
00Transparent colour indexPalette entry 0 is drawn as fully transparent.
00Block terminatorA zero-length sub-block that closes the block.
Image descriptor Where the image sits on the canvas and how big it is.
2CImage separator0x2C (“,”) starts an image.
00 00LeftThe image starts 0 px from the left edge of the canvas.
00 00TopThe image starts 0 px from the top edge of the canvas.
01 00Image width1 px.
01 00Image height1 px.
00Packed flagsNo local colour table, not interlaced. The image uses the global palette.
Image data The pixels, compressed with LZW and split into sub-blocks of up to 255 bytes.
02LZW minimum code size2, so compressed codes start 3 bits wide.
02Sub-block size2 bytes of compressed data follow.
44 01Compressed pixelsLZW codes packed from the lowest bit up. See how they decode below.
00Block terminatorA zero-length sub-block that closes the block.
Trailer One byte that marks the end of the file.
3BTrailer0x3B (“;”) ends the file.

Inside the packed bytes

Three bytes each store several small settings. Bit 7 is the leftmost.

Logical screen descriptor 0x80
1Global colour table present
000Colour resolution
0Palette sorted by importance
000Table size: 2^(n+1) entries
Graphic control extension 0x01
000Reserved
000Disposal method
0Wait for user input
1Transparency on
Image descriptor 0x00
0Local colour table present
0Interlaced
0Palette sorted by importance
00Reserved
000Local table size

How two bytes hold one pixel

With a minimum code size of 2, the decoder reads 3-bit codes. Code 4 clears the table, code 5 ends the image, and codes 0 to 3 are palette entries. The bytes 44 01 are read from the lowest bit up:

0x44 010001000x01 00000001

  1. 001100 = 4Clear: start with a fresh table
  2. 000000 = 0Pixel: palette entry 0
  3. 101101 = 5End of image
  4. 0000000 Unused padding bits

Bigger images use the same trick: every new code stands for a run one pixel longer than the last, so a 1000×1000 transparent GIF takes only 1,743 bytes.

Can it be smaller?

Yes, if you drop parts that decoders tolerate losing. We fed each variant to three browser engines and to Pillow and recorded what they drew.

SizeVariantChromiumFirefoxWebKitPillow
43The standard file on this page.TransparentTransparentTransparentTransparent
42No trailer byte. Decoders stop at the end of the data anyway.TransparentTransparentTransparentTransparent
37No palette at all. Still valid: the spec lets decoders use their own palette, and index 0 is transparent anyway.TransparentTransparentTransparentTransparent
36No palette and no trailer.TransparentTransparentTransparentTransparent
35No transparency block: the pixel is drawn in palette colour 0, white.WhiteWhiteWhiteWhite
35The 1987 format. It has no way to mark a colour transparent.WhiteWhiteWhiteWhite
34Transparency block but no compressed pixels.TransparentTransparentTransparentError
33The same without the trailer.TransparentTransparentTransparentError
29No palette and no transparency. Each engine picks its own colour.BlackWhiteTransparentBlack
26An image with no compressed data at all.TransparentTransparentTransparentError
14Header, canvas size and trailer only. There is no image in it.TransparentErrorTransparentError

Use 43 bytes when it must work everywhere. 37 bytes is still valid GIF and was transparent in every engine we tested. Below that you depend on decoder leniency, and the 29-byte file shows how engines disagree.

Checked on September 23, 2026 with Chromium 153.0.8010.12, Firefox 155.0, WebKit 26.6, Pillow 12.2.0.

Make one any size

Transparent or a solid colour, from 1×1 up to 65535×65535. It is generated in your browser; nothing is uploaded.

Fill
Common sizes

1×1 · 43 bytes

Download GIF

Serve it from your stack

191 ready-to-run snippets. Pick yours: each one answers at the path you choose with an image/gif response. If you changed the size or colour above, the snippets use that GIF.

Express JavaScript

Install
npm i express
File
server.mjs
Run
node server.mjs
import express from 'express';

const GIF = Buffer.from('R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', 'base64');

const app = express();

app.get('/pixel.gif', (req, res) => {
  res.set('Cache-Control', 'no-store');
  res.type('gif').send(GIF);
});

app.listen(8080);

We ran this snippet and compared the bytes it returned. Open page

What it is used for

  • Tracking pixels and beacons: the server logs the request and answers with the smallest valid image.
  • Placeholders for lazy-loaded images, so the img tag is valid before the real source arrives.
  • Fixed-size spacers in HTML email, where CSS support is patchy.
  • Tests and mocks that need a real image without shipping one.

Tracking pixels are less reliable than they look

Apple Mail preloads remote images through a proxy when Mail Privacy Protection is on, so an “open” may never have been a person. Gmail also fetches images through its own proxy and caches them. Many clients block remote images by default. For page analytics, navigator.sendBeacon() or a 204 No Content response is often a better fit than an image.

Questions

Why is it called empty when it has a pixel?
A GIF must have at least one pixel. This one is 1×1 and its only colour is marked transparent, so nothing shows.
Is the 43-byte file valid?
Yes. It follows the GIF89a specification exactly, and every engine in the table above draws it as transparent.
Why a GIF and not a PNG or WebP?
It is smaller than a minimal transparent PNG, and every browser, email client and image library from the last 35 years can read it.
Should I use a data URI or a file?
A data URI saves a request and suits placeholders and CSS. A file or endpoint is needed when the request itself is the point, as with tracking pixels.
Which Content-Type should I send?
image/gif. Add Cache-Control: no-store if every request must reach your server.