
One-Second Deploys? We Didn’t Believe It Either
Let me introduce you to someone: they just released a new app, they started to tell people about it, and now they find themselves checking their Postgres database every 15 minutes to see if anyone has signed up. The thought of setting up Zapier or Mixpanel for a few simple product alerts puts them in physical agony.
That was me just a few months ago.
Alright, I thought: I’ll write a script, upload it to a Lambda function, and set up an EventBridge schedule to run it every hour.
After over two hours of writing CDK, debugging permissions, waiting in the slow CloudFormation loop, and setting up a package to deploy, I finally received a Discord notification.
Wahooo!!…? Not really.
Because that’s how I spent my entire Saturday morning.
Look at this code:
import { DiscordNotification } from "@penseapp/discord-notification";
const notify = new DiscordNotification(
"Product Alerts (Hourly)",
import.meta.env.DISCORD_WEBHOOK_URL
);
const users = await Bun.sql`
SELECT COUNT(*) as total FROM users WHERE created_at >= NOW() - INTERVAL '1 hour';
`;
if (users[0].total > 0) {
await notify
.infoMessage()
.addUsername("hypebot")
.addTitle("Engagement")
.addField({ name: "New Users", value: users[0].total })
.sendMessage();
}
How is it possible that with the simplicity of a cloud, the magic of IaC, and the truly crisp API of the Bun runtime — a mere 20 lines took over two hours to ship?
That couldn't be right. There had to be a better way.
Spoiler alert: There was a better way.
We built it and added it to Railway.
That's what we're announcing today.
Allow me to show you how to deploy that same code in a secure Railway environment in 45 seconds:
No package manager, no GitHub repo, no IaC, no container builds. Just code to deploy.
We're calling this feature Railway Functions, and it's available today in GA.

It’s now possible to create a Function anywhere on the Railway canvas
Let's get into how it works.
With Functions, we aim to cut out every step that isn’t absolutely necessary for running native code in a container and deploy it in under 5 seconds.
Behind the curtain, Functions run on the same infraless compute that Services do, which means you can still use volumes, variables, and other features you know and love.
Here's what's happens when Railway runs a Function:
1. Parse and analyze: We first parse your source code into an AST, determine its dependencies, then generate a package.json file on-the-fly. Our analyzer allows you to pin versions of packages without the need for a lockfile or package.json.
import pkg from 'pkg@6.2.0'
import pkg from 'pkg@^6.2.0'
import pkg from 'pkg@~6.2.0'
import pkg from 'pkg@next'
import pkg from 'pkg' // evaluates to @latest
const pkg = await import("pkg")
2. Install dependencies: Dependencies are then installed at the beginning of each deploy using bun install
. We tested every package manager under the sun and found Bun consistently outperformed the competition by up to 10x. With Bun, our entire deploy step takes less time to finish than npm install fastify
did.
3. Run your code: Bun allows you to execute TypeScript/JavaScript without transpiling first. Once we’ve stripped the version strings from your imports, we can then run your code as is without a bundler and Bun will strip the types.
Shortening the feedback loop to seconds isn't a marginal improvement — it fundamentally changes how you work. When you can deploy in 1 second, you're free to experiment, iterate, and ship while staying in flow.

A real Function that took 00:01 seconds to deploy
Today Functions offers support out of the box for TypeScript, but in the future we'll be adding more language support.
To get started, head over to Railway, open up the canvas, and add a new Function service. We provide a few code examples out of the box, including a REST API, a landing page in JSX, and a cron utility.
If you're curious about other use cases, you can also check out the docs.
Either way, let us know what you want to see next in the Functions thread in Help Station.
Happy shipping.