RSS către 66 de rețele sociale: Facebook, Instagram, X, LinkedIn, Telegram și altele Blog Afiliere Contact
Autentificare Începeți gratuit
Updated: 2026-11-10
Heroku RSS Feed: Small App, Config Vars and Cache

Short answer: To serve an RSS feed from Heroku, deploy a small web app with a Procfile, read the port from the environment, build the XML from your data store, escape every value and return it with the RSS content type and cache headers. Store settings in config vars, check whether your dyno type goes to sleep when idle and what that means for the first request, attach a custom domain with a managed certificate, and put a cache in front if traffic grows. Tools such as PostRSS can then read the stable feed address around the clock and share each new item on social networks.

Heroku popularized a simple way to run web applications: push your code, and the platform builds it, starts it in a lightweight container called a dyno and gives it an address. Many small publishers, startups and internal tools still use it because it needs almost no server administration. An RSS feed is a natural small app for this model. It has one route, reads data and returns XML. This guide explains how to build and deploy such a service, which platform settings matter for a document that tools fetch every few minutes, how to handle idle dynos and caching, and how to avoid the common mistakes. Plan names, dyno types and prices change over time, so check the current platform documentation before you decide.

When a feed app on Heroku makes sense

A dedicated feed service is useful when your content does not live on a web server that already produces feeds. Perhaps the articles sit in a headless content system, a database or a spreadsheet. Perhaps you want to merge several sources into one feed, or produce a feed of products from an API. If your site runs on WordPress or a similar system, its own feed is easier to keep correct, and you do not need a separate app. If you already host an application on Heroku, adding a route for the feed is often the simplest option, because the data and the deployment pipeline are already there.

A minimal feed app

The example uses Node.js with the Express library, but the structure is the same in any language: read the latest items, build the XML, escape every value and set the headers.

const express = require("express");
const { latestPosts } = require("./content");

const app = express();
const SITE = "https://example.com";

const esc = (s) => String(s)
  .replace(/&/g, "&" + "amp;")
  .replace(/</g, "&" + "lt;")
  .replace(/>/g, "&" + "gt;");

app.get("/feed.xml", async (req, res) => {
  const posts = await latestPosts(30);
  const items = posts.map((p) =>
    "<item><title>" + esc(p.title) + "</title>" +
    "<link>" + SITE + "/" + p.slug + "/</link>" +
    "<guid isPermaLink='true'>" + SITE + "/" + p.slug + "/</guid>" +
    "<pubDate>" + new Date(p.published).toUTCString() + "</pubDate>" +
    "<description>" + esc(p.summary) + "</description></item>"
  ).join("");
  const xml = "<?xml version='1.0' encoding='UTF-8'?><rss version='2.0'><channel>" +
    "<title>Example blog</title><link>" + SITE + "</link>" +
    "<description>News from Example</description>" + items + "</channel></rss>";
  res.set("Content-Type", "application/rss+xml; charset=UTF-8");
  res.set("Cache-Control", "public, max-age=300");
  res.send(xml);
});

app.listen(process.env.PORT || 3000);

Two details matter here. The platform assigns the port through an environment variable, so the app must read it and not use a fixed number. And every text value passes through an escape function, because one stray ampersand in a title makes the whole feed invalid.

Tell the platform how to start the app

A small file named Procfile in the root of the project declares the process types. A web process receives traffic from the router.

web: node server.js

The project also needs its dependency file, such as the package file with the engine version, so the build knows which runtime to install. Deploy with a push to the platform’s git remote or by connecting a repository and enabling automatic deploys. After the build finishes, the app is available on an address under the platform’s domain. Open the feed in a browser, check the content type with a command line client and paste the address into the W3C Feed Validation Service before you share it.

Keep configuration in config vars

Database addresses, API keys and the base address of your site belong in config vars, which the platform exposes as environment variables. Never commit them to the repository or bake them into the code. Set the site address as a variable too, so the same code can run in a test app and in production with different values. When you change a config var, the platform restarts the dynos, so make changes at a quiet moment. Keep a list of the variables your app expects in the project notes, so a new colleague can recreate the setup.

Idle dynos and the first request

Some dyno types are designed to sleep after a period without traffic and wake when a request arrives, which makes the first answer slower. Others stay running all the time. Check the documentation for the type you use, and decide what matters for your feed. A feed that an auto-poster checks every minute or two rarely stays idle for long, but a feed checked less often may. A slow first answer is usually harmless, though a few clients give up after several seconds. If the delay is a problem, choose a dyno type that does not sleep, keep the app small so that it starts quickly, or put a cache in front of it so most requests never reach the app.

Cache so the app works less

The cache header in the example lets browsers and shared caches reuse the answer for a few minutes. If the data source is slow, add a short in-memory cache inside the app that refreshes after a minute, so many requests share one build. If traffic grows, put a content delivery network in front and make the cache key the path alone, so that query strings added by tools do not create new copies. The principles are the same as in the guide to a Cloudflare Workers feed and the guide to an AWS Lambda feed. When you publish an article, either wait for the lifetime to expire or purge the feed path.

Do not rely on the local disk

The file system of a dyno is temporary. Files written during a run disappear when the dyno restarts, which happens regularly, including after each deployment and each config change. The app must therefore build the feed from a database, an API or an object store, and never from files that it wrote earlier. If you want to store a generated feed file, upload it to external storage and serve it from there. Treat every dyno as disposable, and the app will survive restarts without anyone noticing.

Attach a custom domain and keep the address stable

The default address belongs to the platform. A feed address is stored in readers, in search tools and in the settings of every auto-poster, so it should belong to you. Add a domain or subdomain that you control, create the DNS record that the platform asks for and let it manage the certificate. Redirect plain HTTP to HTTPS. If you later move the app, you change where the domain points, and the feed address stays the same. Use the same canonical address in the link tags of your pages so that tools can discover it.

Use a review app or staging copy

Because a feed is consumed by other systems, a broken release is noticed late, often after an auto-poster has already shared something odd. Create a second app as a staging copy, deploy each change there first and compare its feed with the production feed. The number of items, their order, the identifiers and the dates should match, and only intended differences should appear. Point the staging app at a copy of the data, not at production data, and keep it private or clearly marked so that search tools do not index it. When the comparison looks right, promote the same build to production. This routine takes a few minutes and prevents most mistakes that readers would otherwise find for you.

Plan for scale and cost

A feed is small, so one dyno is enough for most publishers, especially with a cache in front. Add a second dyno only if you need availability during deployments or you see sustained load. Watch response time and memory in the platform’s metrics, and set a budget alert so that a misbehaving client cannot create a surprise bill. If a single tool fetches the feed far too often, the logs will show its user agent, and you can ask its owner to slow down or put a rate limit in front of the app. Reviewing the metrics weekly for the first month teaches you the normal pattern of your feed.

Monitor the feed

Use the platform’s logs to watch for errors and slow responses, and add an external uptime check that fetches the feed, verifies the status and the content type and alerts you if the content has not changed for an unusually long time. A feed can be reachable and still wrong: an empty channel, a stale date or a broken character all pass a simple status check. After every release, validate again and compare the identifiers of items with the previous version. Identifiers must not change, otherwise readers and auto-posters may treat old articles as new.

Handle errors from the data source

The feed app depends on a database or an API, and either can fail. Set a short timeout on every call, so the app does not hang until the router gives up. If the call fails, serve the last good copy from a small cache, with a normal status, and log the problem. Returning an error status makes some tools retry more often, which adds load exactly when the source is struggling. Add an alert for repeated failures so you can look at the cause the same day. A feed that is a little old for an hour is far better than a feed that disappears.

Common mistakes to avoid

  • A fixed port. The platform assigns it through the environment.
  • Unescaped characters. One ampersand invalidates the XML.
  • Secrets in the repository. Use config vars.
  • Files on the dyno disk. They disappear on restart.
  • Relative links. Items need complete addresses with the domain.
  • No cache headers. Every check reaches the app and the data source.

How PostRSS works with a feed hosted on Heroku

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; PostRSS can check the feed as often as every minute and publishes each new item with its real image and link to the networks you select among its 66 supported networks. A feed that answers quickly and carries cache headers is cheap to check. Add UTM parameters to the posted links to see which network brings readers. See the PostRSS features page for the options and the pricing page for plan limits.

Lecturi conexe

The bottom line

Heroku can host a dependable RSS feed with very little code. Read the port from the environment, build the XML from a durable data source, escape every value, send the RSS content type and cache headers, keep secrets in config vars, understand how your dyno type behaves when idle, attach a custom domain and monitor the result. Then connect the address to an auto-poster, so each new article reaches your audience on social networks without further work.

FAQ

Can I host an RSS feed on Heroku?

Yes. A small web app that returns XML with the RSS content type works well. Declare a web process in the Procfile, read the port from the environment and deploy.

Does an idle dyno break feed readers?

Rarely. Some dyno types sleep when idle, so the first request is slower. Choose a type that stays running or add a cache if you want consistently fast answers.

Where should I keep database passwords?

In config vars, which the platform exposes as environment variables. Never commit them to the repository.

Can the feed be stored as a file on the dyno?

No. The local disk is temporary and is cleared on restart. Build the feed from a database or serve a file from external storage.

Can PostRSS read a feed hosted on Heroku?

Yes. PostRSS reads any valid RSS or Atom address that is reachable without a login, wherever it is hosted.

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.

Mai multe instrumente de la echipa noastră

Create de Internet Solutions, echipa din spatele PostRSS. Fiecare produs vă economisește timp în felul său.