OG Image Size: 1200×630, Crops and File Limits
The right OG image size is 1200×630 (1.91:1). Platform limits with sources, how many pixels each preview shape crops, and measured file sizes at 1x and 2x.
The right OG image size is 1200×630 pixels, a 1.91:1 ratio, saved as PNG or JPEG under 5 MB. That size meets Facebook's recommendation, sits within one pixel of LinkedIn's minimum, and loses only 15 pixels top and bottom in X's 2:1 card. Declare the size in the page so platforms can lay out the card before they download it:
<meta property="og:image" content="https://example.com/cards/my-post.png"> <meta property="og:image:width" content="1200"> <meta property="og:image:height" content="630"> <meta property="og:image:alt" content="Title card for the post My post">
The rest of this guide is the detail behind that answer: what each platform publishes and where, how many pixels each preview shape crops from common sizes, and what 2x images cost in file size. For how to generate the image itself, see the guide to generating OG images from HTML.
Tested on 2026-10-18 with Node 22.18 and
[email protected](bundled Chromium) on macOS, Apple M1 Pro. The crop table is computed by the script below; the file sizes were measured from local Chromium screenshots. Facebook and LinkedIn limits were read from their documentation the same day.
Published limits per platform
Only some platforms publish numbers. Where we could not find or load a primary source, the table says so rather than repeating numbers that circulate without one.
| Platform | Reads | Recommended size | Minimum | Max file size | Source, check date |
|---|---|---|---|---|---|
og:image, og:image:width/height |
at least 1200×630, ratio close to 1.91:1 | 200×200; 600×315 for the large link layout | 8 MB | Meta: images in link shares, 2026-10-18 | |
og:image |
ratio 1.91:1 | 1200×627 | 5 MB | LinkedIn help: sharing module, 2026-10-18 | |
| X | twitter:image, else og:image |
2:1 for summary_large_image, 1:1 for summary |
300×157 and 144×144 | 5 MB | X developer docs for cards; the page did not load for us on 2026-10-18, so re-check these values |
| Slack | og:image |
no published spec found | none found | none found | not checked against live unfurls |
| Discord | og:image |
no published spec found | none found | none found | not checked against live unfurls |
| iMessage | og:image |
no published spec found | none found | none found | not checked against live unfurls |
og:image |
no published spec found | none found | none found | not checked against live unfurls | |
| Telegram | og:image |
no published spec found | none found | none found | not checked against live unfurls |
Two details in Meta's page matter more than the numbers. Images smaller than 600×315 still show, but as a much smaller preview. And the crawler accepts only gzip and deflate encodings, so a server or CDN that sends Brotli even when the request does not ask for it can fail on Facebook while working in every browser.
For the chat apps without a spec, the safe approach is the same as for the others: a wide 1.91:1 image with the important content in the middle, as the crop table below shows.
How many pixels each preview shape crops
When a platform shows your image in a frame of a different shape, it scales the image to fill the frame and trims the overflow. We computed the trim for common source sizes against the three frame shapes that matter: 1.91:1 (Facebook, LinkedIn), 2:1 (X large card) and 1:1 (square thumbnails). The numbers assume a centred crop, which is the common behaviour; a platform is free to crop differently.
| Source | Ratio | In a 1.91:1 frame | In a 2:1 frame | In a 1:1 frame |
|---|---|---|---|---|
| 1200×630 | 1.905 | 2 px tall (0.3%) | 30 px tall (4.8%) | 570 px wide (47.5%) |
| 1200×628 | 1.911 | 1 px wide (0.1%) | 28 px tall (4.5%) | 572 px wide (47.7%) |
| 1200×627 | 1.914 | 2 px wide (0.2%) | 27 px tall (4.3%) | 573 px wide (47.8%) |
| 1200×600 | 2.000 | 54 px wide (4.5%) | none | 600 px wide (50.0%) |
| 1200×675 (16:9) | 1.778 | 47 px tall (7.0%) | 75 px tall (11.1%) | 525 px wide (43.8%) |
| 1200×1200 | 1.000 | 572 px tall (47.7%) | 600 px tall (50.0%) | none |
| 1080×1350 (4:5) | 0.800 | 785 px tall (58.1%) | 810 px tall (60.0%) | 270 px tall (20.0%) |
What the table tells you:
- 1200×630, 1200×628 and 1200×627 are the same image for practical purposes. The differences are one or two pixels. Pick 1200×630 and stop worrying about the 627 versus 628 versus 630 debate.
- 16:9 images lose 7% of their height in Facebook and LinkedIn previews and 11% in X's large card. A 1920×1080 slide or video thumbnail used as
og:imagegets its title cut if the title sits near an edge. - Square and portrait images are a poor fit for
og:image. A 1080×1350 Instagram-style image loses more than half its height in a wide frame. - Any square crop of a wide card keeps only the middle 630 pixels of 1200. If a platform shows a square thumbnail, your logo in the left corner is gone.
The script that produced the table, so you can add your own sizes:
// crop.mjs: how many source pixels each preview shape cuts from an image, assuming a centred // "cover" crop (scale to fill the frame, trim the overflow equally on both sides). const sources = [[1200, 630], [1200, 628], [1200, 627], [1200, 600], [1200, 675], [1200, 1200], [1080, 1350]]; const frames = { '1.91:1': 1.91, '2:1': 2, '1:1': 1 }; const rows = []; for (const [w, h] of sources) { const row = { source: `${w}x${h}`, ratio: (w / h).toFixed(3) }; for (const [label, r] of Object.entries(frames)) { if (w / h > r) { const keep = Math.round(h * r); row[label] = `${w - keep} px wide (${((w - keep) / w * 100).toFixed(1)}%)`; } else if (w / h < r) { const keep = Math.round(w / r); row[label] = `${h - keep} px tall (${((h - keep) / h * 100).toFixed(1)}%)`; } else row[label] = 'none'; } rows.push(row); } console.table(rows);
The safe area that survives every crop
Overlay the crops on a 1200×630 card and three zones appear:
- The outer 15 px at top and bottom disappear in X's 2:1 card. Keep borders and footers clear of them.
- The middle 1200×600 is visible in every wide preview. Put the title here.
- The middle 630×630 is all that a square crop keeps. If square thumbnails matter to you, the logo and the first words of the title belong here, not in a corner.
In practice: 80 px side padding and 60 px top and bottom padding, with the title vertically centred, keeps a card readable in all three shapes. Small text is the other risk. Chat apps show the card at a fraction of its full width, so judge legibility from the overlay output scaled down to the size of a chat preview, not at 100%.
To check your own template, this script screenshots a card and draws the 2:1 and 1:1 crop boxes on it:
// overlay.mjs: screenshot a 1200x630 card and draw the 2:1 and 1:1 centre crops over it. // Usage: node overlay.mjs <card-url> out.png import { chromium } from 'playwright-core'; const [cardUrl, out = 'overlay.png'] = process.argv.slice(2); if (!cardUrl) { console.error('usage: node overlay.mjs <card-url> [out.png]'); process.exit(2); } const W = 1200, H = 630; const crops = [ { label: '2:1 (X summary_large_image)', w: W, h: Math.round(W / 2), color: '#f43f5e' }, { label: '1:1 (square thumbnails)', w: H, h: H, color: '#22d3ee' }, ]; const browser = await chromium.launch(); try { const page = await browser.newPage({ viewport: { width: W, height: H } }); const res = await page.goto(cardUrl, { waitUntil: 'networkidle' }); if (!res?.ok()) throw new Error(`card answered HTTP ${res?.status()}`); await page.evaluate(({ W, H, crops }) => { for (const c of crops) { const box = document.createElement('div'); Object.assign(box.style, { position: 'fixed', zIndex: 2147483647, pointerEvents: 'none', left: `${(W - c.w) / 2}px`, top: `${(H - c.h) / 2}px`, width: `${c.w}px`, height: `${c.h}px`, outline: `3px dashed ${c.color}`, outlineOffset: '-3px', font: '600 16px system-ui', color: c.color, boxSizing: 'border-box', padding: '6px', }); box.textContent = c.label; document.body.append(box); } }, { W, H, crops }); await page.screenshot({ path: out }); console.log(`wrote ${out}`); } finally { await browser.close(); }
Install with npm i [email protected] and npx playwright-core install chromium, then run node overlay.mjs https://example.com/og/my-post overlay.png. It works with any card URL that renders at 1200×630, including a local file:// path.
1x or 2x: what retina cards cost
A 2x card (2400×1260) looks sharper on high-density screens if the platform keeps the full resolution. It also has four times the pixels. We rendered two designs at both scales with local Chromium and saved each as PNG and as JPEG at quality 80:
| Design | Pixels | PNG | JPEG q80 |
|---|---|---|---|
| Flat text card (solid background, one headline) | 1200×630 | 45 KB | 48 KB |
| Flat text card | 2400×1260 | 98 KB | 105 KB |
| Busy photo-like card (per-pixel noise over a gradient) | 1200×630 | 1,672 KB | 201 KB |
| Busy photo-like card | 2400×1260 | 5,137 KB | 513 KB |
Method: one page per design, deviceScaleFactor 1 and 2 in a Playwright context, page.screenshot() with type: 'png' and type: 'jpeg', quality: 80, one run each on 2026-10-18. The noise card is a deliberately hard case for PNG; real photos usually compress better than random noise.
Two conclusions:
- For flat designs, the format barely matters and 2x is affordable. PNG keeps text edges crisp, so it is the better default.
- For photographic designs, PNG at 2x can break the limit. 5,137 KB is over the 5 MB maximum that LinkedIn publishes. Use JPEG for photo-heavy cards, and do not go to 2x without checking the file size.
Platforms recommend 1200×630, not 2400×1260, and none of the sources above promises to keep a larger file at full resolution. A 1x card is the default we would ship.
Render the right size with presets
If you render cards from an HTML template with RenderScreenshot, the presets set the viewport for each shape:
| Preset | Size | Use for |
|---|---|---|
og_card |
1200×630, PNG | og:image for Facebook, LinkedIn, Slack, Discord |
twitter_card |
1200×600, PNG | an exact 2:1 twitter:image |
twitter_card_large |
1200×628, PNG | a 1.91:1 image for summary_large_image |
link_preview |
800×600, PNG | chat-app style previews |
curl -sS -o card.png -H "Authorization: Bearer $RS_API_KEY" \ "https://api.renderscreenshot.com/v1/screenshot?url=https%3A%2F%2Fexample.com%2Fog%2Fmy-post&preset=og_card"
For a photographic card, override the format and quality: add format=jpeg&quality=80 to the same request. For a public og:image tag, use a signed URL instead of a Bearer token. The OG image API overview shows the setup in six languages, and you can create a free account with 150 credits a month to try it on your own template.
Checklist
- 1200×630, ratio 1.91:1, PNG for flat designs, JPEG for photos.
- Under 5 MB, which covers both LinkedIn and X; Facebook allows 8 MB.
og:image:width,og:image:heightandog:image:altset and matching the file. In our crawl of top sites, 22.6% of declared sizes were wrong.- Title inside the middle 1200×600, logo inside the middle 630×630 if square crops matter.
- Served uncompressed or with gzip, never Brotli-only, for Facebook's crawler.
- If the preview still does not appear, work through the twelve causes of a missing OG image.
Last tested 2026-10-18.
Related in this topic
- Generate OG Images From HTML: A Production Guide Generate Open Graph images from an HTML template: platform size limits, escaping, signed URLs without redirects, cache-safe expiry and a Next.js example.
- The State of OG Images: A 10,000-Site Crawl We crawled the top 10,000 home pages for og:image and Twitter card tags: adoption, sizes, formats, file weight and broken image URLs, with our method.
- Next.js OG Images: opengraph-image.tsx vs a Route Handler Dynamic OG images in Next.js 16: opengraph-image.tsx, the tags it emits, measured static vs per-request timings, fonts, and when a screenshot route wins.
- OG Image Not Showing? 12 Causes and a Checker Script OG image not showing in Slack, LinkedIn or X? Twelve causes in the order to check them, a tested Node script that finds each one, and the fix for every case.
- Rails OG Images: meta-tags, an ERB Card and Signed URLs Dynamic Open Graph images in Rails 8: an ERB card route, the meta-tags gem, a signed og:image helper, Minitest tests and what allow_browser does to crawlers.
- Twitter Card Image Size: summary vs summary_large_image X card image sizes: 1200×600 (2:1) for summary_large_image, a square for summary. What 1200×630 and 1200×628 lose to the crop, and the tags that pick the card.