RSS 66 közösségi hálózatra: Facebook, Instagram, X, LinkedIn, Telegram és további platformok Blog Partnerprogram Kapcsolat
Bejelentkezés Kezdje ingyen
Updated: 2026-11-03
Nginx RSS Feed: Content Type, Caching and Compression

Short answer: Nginx can serve your RSS feed correctly in a few lines of configuration. Map the feed to the RSS content type with a UTF-8 charset, because the default type table serves .xml files as plain XML. Turn on compression for feed types, keep the built-in ETag and Last-Modified validators, add a short cache lifetime and, when the feed comes from an application, put a small proxy cache with stale fallback in front of it. Do not let rate limits or bot rules block the tools that poll the address, then test the live feed with curl and connect it to an auto-poster.

Most feeds pass through Nginx on the way to readers, whether it serves a static file or sits in front of a CMS, a Node service or a PHP application. That makes the web server the place where many feed problems start or end: a wrong content type, a missing compression rule, a cache that holds an old copy for an hour, a rate limit that answers an auto-poster with an error. This guide shows a working configuration for a static feed and for a proxied feed, explains each directive in plain language and lists the traps that are easy to meet after a server upgrade. Directive names are stable across current versions, but always run the configuration test before you reload.

Serve a static feed with the right content type

If a script writes a file such as feed.xml into your web root, Nginx can serve it without any other software. The first surprise is the content type. The default types table maps the xml extension to text/xml, and the rss extension to application/rss+xml. Many generators write feed.xml, so the server announces plain XML. Most tools accept it, but the RSS type is the clearer signal, and some validators warn about the mismatch. A single location block fixes it.

server {
    listen 443 ssl;
    http2 on;
    server_name example.com;
    root /var/www/example.com/public;

    location = /feed.xml {
        default_type application/rss+xml;
        charset utf-8;
        expires 5m;
        add_header Cache-Control "public";
        try_files $uri =404;
    }
}

The exact-match location applies only to this address, so the rest of the site is untouched. The default type is used because the table has no better answer in this block, and the charset directive adds the UTF-8 label to the content type for the types in its list. The expires directive sets a lifetime of five minutes and also writes a matching cache header. The meaning of the header is explained in the guide to the content type header.

SettingWhat it doesTypical value
default_typeContent type when the table has no matchapplication/rss+xml
charsetAdds the character set to the headerutf-8
expiresSets a cache lifetime for clients5m
gzip_typesLists the types that are compressedInclude the RSS and Atom types
proxy_cache_validLifetime of a stored copy200 for 5m

Compression

An XML feed compresses very well, often to a fraction of its size. Nginx compresses text and HTML by default when gzip is on, but not the feed types, so list them.

gzip on;
gzip_vary on;
gzip_min_length 512;
gzip_types application/rss+xml application/atom+xml text/xml application/xml;

Put the lines in the http block so that they apply everywhere. The vary directive adds a header that tells caches that the answer depends on the encoding. Check the result with a request that accepts compressed data. Compression helps tools that poll often, and the details are covered in the feed compression guide. One side effect is worth knowing. When Nginx compresses an answer on the fly, it changes a strong ETag into a weak one, which is correct behaviour and does not break conditional requests.

Validators and conditional requests

For static files, Nginx adds an ETag and a Last-Modified header on its own, and it answers a conditional request with a 304 status and no body. You do not need to enable anything, and that is the best reason to keep a static feed when your content does not change every minute. If a script rewrites the file, write it to a temporary name and rename it into place, so that a request never reads half a document. The mechanism is described in the guide to ETags and conditional requests.

Proxy a feed from an application

When the feed is produced by a CMS or a service, Nginx can store the answer for a few minutes and protect the application from repeated requests. It can also keep serving an older copy when the application fails, which is exactly what a feed needs.

proxy_cache_path /var/cache/nginx/feed levels=1:2 keys_zone=feed:10m max_size=50m inactive=1h;

location = /feed.xml {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Host $host;
    proxy_cache feed;
    proxy_cache_valid 200 5m;
    proxy_cache_lock on;
    proxy_cache_background_update on;
    proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
    add_header X-Cache-Status $upstream_cache_status always;
}

A stored answer lives for five minutes. While it is being refreshed, the lock makes other requests wait and the stale option lets them receive the old copy, so a burst of polling tools causes one call to the application and not fifty. If the application returns an error or times out, visitors still get the last good feed. The extra header shows whether an answer was a hit, a miss or stale, which is useful when you test. Remove it later if you do not want to expose it. Background on delays is in why auto-posted content sometimes lags, and on slow servers in the guide to feed timeouts.

The add_header trap

Headers set with add_header at one level replace the ones from the level above, they do not add to them. If your server block sets security headers and your feed location sets a cache header, the feed answer carries only the cache header. This is not harmful for a feed, but it surprises people who audit headers. If you need both, repeat the lines in the location or put them in a shared file that you include in both places.

Redirects, canonical addresses and trailing slashes

Keep one canonical address for the feed and use it everywhere: in the page link tags, in the sitemap notes and in the auto-poster. If an older address must survive, redirect it with a permanent status.

location = /feed { return 301 /feed.xml; }
location = /rss { return 301 /feed.xml; }

Tools follow redirects, but every redirect costs a request and can confuse validators, and a chain of two or three redirects is a common reason for failures. Also redirect plain HTTP to HTTPS at the server level, and make sure the feed address you publish already uses HTTPS, so that no tool starts with an insecure request. The meaning of each status is explained in the guide to feed status codes.

Several feeds and a wildcard location

Sites that offer a feed for each category or language often use a pattern. A regular expression location can map every address that ends in .xml under a feed folder to the same rules, and a prefix location with the caret tilde modifier does the same for a folder without invoking the regular expression engine. Prefer the prefix form when you can, because it is easier to read and cannot match by accident. Whatever you choose, keep the list of feed addresses in one place and review it when a section is added or removed, so that no feed is left without the correct type, the compression rule and the cache settings.

Do not block the readers

Two protection features cause quiet feed outages. The first is rate limiting. A limit that is tuned for browsers can answer a polling tool with an error when several tools share an address, so give the feed its own location without a limit, or with a generous one. The second is bot filtering. Rules that block empty or unknown user agents, or that challenge requests from data centres, also block auto-posters and feed readers. If you use a firewall service in front of Nginx, add an exception for the feed path. When a tool reports that the feed is forbidden or unreachable, check these two settings before you look anywhere else.

Read your own logs

The access log shows who polls the feed and how often. Filter it for the feed path and look at three things: the share of 304 answers, which should be high when validators work, the share of errors, which should be near zero, and the interval between requests from the same client. A client that asks every few seconds is misconfigured, and a client that never comes is probably blocked. If the log is large, add a separate log file for the feed location so that it is easy to read.

Test the configuration

Always check the syntax before you reload, then test from outside the server.

sudo nginx -t && sudo systemctl reload nginx
curl -sI https://example.com/feed.xml
curl -sI -H 'Accept-Encoding: gzip' https://example.com/feed.xml
curl -sI -H 'If-None-Match: "paste-the-etag-here"' https://example.com/feed.xml
  • The first request returns 200 and the RSS content type with a UTF-8 charset.
  • The second shows a content encoding header, which means that compression works.
  • The third returns 304 when the validator matches.
  • The address passes the W3C Feed Validation Service without errors.
  • A request through your normal network and one from a different location give the same answer.

A longer routine is in the feed validation guide, and a shorter one in debugging a feed with curl.

Common mistakes to avoid

  • Serving the feed as plain XML. Set the RSS content type for the feed location.
  • No compression for feed types. List them in the gzip types.
  • A cache lifetime of hours. New posts arrive late on social channels.
  • Rate limits on the feed. Polling tools receive errors.
  • Bot rules without an exception. Auto-posters are blocked as unknown clients.
  • Reloading without a test. A typo takes the whole site down.

How PostRSS works with a feed served by Nginx

PostRSS has been publishing RSS and Atom feeds to social networks since 2014. Paste the address of your feed, connect your accounts and choose how each post is built from the title, the description or the page title. PostRSS checks the feed as often as every minute and shares each new entry, with its image and link, to the channels you choose among 66 supported networks, messengers, team chats and blogs, including LinkedIn, X, Bluesky, Mastodon and Telegram. Keyword filters, UTM parameters and posting windows let you tune each channel. See the PostRSS features page and the plan limits on the pricing page. More developer guides are under the Technical Guide tag.

Kapcsolódó olvasmányok

The bottom line

Nginx is a small part of your feed and a common source of trouble. Give the feed address its own location with the RSS content type and a UTF-8 charset, compress the feed types, keep the validators that static files bring, cache an application feed for a few minutes with a stale fallback and exempt the address from rate limits and bot rules. Test the syntax, test the headers from outside and then connect the address to an auto-poster, so that every article you publish reaches your social channels without surprises.

FAQ

Which content type should Nginx send for an RSS feed?

Use application/rss+xml with a UTF-8 charset. The default table serves .xml files as text/xml, so set the type in a location block for the feed.

Do I need to enable ETags in Nginx?

For static files they are on by default. For a proxied feed, the application should send its own validator, or Nginx can store the answer for a few minutes.

How long should the feed be cached?

A few minutes is a good compromise. A lifetime of hours makes new posts reach your social channels late.

Why does an auto-poster get a forbidden or 429 error?

Usually a bot rule or a rate limit is blocking it. Give the feed address an exception and check your firewall service as well.

Can PostRSS read a feed served by Nginx?

Yes. PostRSS reads any valid RSS or Atom address that is reachable without a login. Paste the address, connect your channels and new articles are shared as soon as they appear.

New guides, once a month

What changed in the networks, what broke, and how to fix it before it costs you reach.

We send a confirmation e-mail first. Unsubscribe any time.

További eszközök csapatunktól

Az Internet Solutions, a PostRSS mögött álló csapat fejlesztései. Mindegyik a maga módján spórol időt.