Serverless isn't just trendy—it's rewriting how software scales.
Netflix streams billions of hours without servers. Coca-Cola automates workflows without infrastructure. Figma and T-Mobile ditch downtime. What do they know that you don't?
The secret? Event-driven serverless code. It's the backbone of apps that scale instantly, cut costs, and survive traffic spikes. No servers. No guesswork. Just code that reacts.
This isn't hype—it's a blueprint. Ready to build smarter? Let's break down how event-driven serverless turns scalability from a challenge into a reflex.
Brief Intro to Serverless
Spoiler alert: servers are still there.
There are multiple definitions for this term online, often filled with complex jargon. The best way I like to define it is:
A "fashion" of deploying your code where YOU don't have to think about the servers running your code.
Let's take an example:
Take Bob. He built mytrashcode.com but panicked at "server setup." He's a developer, not a sysadmin. Instead, he uploaded his code to a cloud provider. They handled security, scaling, and traffic—his site went live. No late-night server meltdowns. No panic during traffic surges. Done.
Why Can't I Manage My Own Servers?
Managing your own servers usually takes one of two paths. You either run physical hardware—like turning an old laptop into a DIY server—or rent a Virtual Private Server (VPS) from providers like DigitalOcean Droplets, Azure VMs, or AWS Lightsail. These fall under IaaS (Infrastructure as a Service), where the cloud company provides the bare-metal infrastructure, but the rest—updates, scaling, security—is entirely up to you.
Does this mean self-managing servers is impossible?
Not at all. Plenty of teams still do it. But managing your own servers comes with a lot of... challenges, including:
- Knowing how to manage infrastructure/hardware.
- Setting up auto-scaling and downscaling.
- Periodically applying system patches and updates to avoid exposing vulnerabilities.
- Configuring proxies, SSL certificate generation, network settings, etc.
Dividing Your Code into Functions
Serverless code doesn't need to be monolithic, i.e., all code doesn't need to be in the same place. It can be a collection of bite-sized, event-triggered functions.
A Function is nothing but a set of code that performs a specific task. When writing your entire code serverless, you'll find that you can divide your code into various functions, each handling a specific part of your application. Let's understand this more deeply with an example:
When Bob first logs into mytrashcode.com as a new user, the system triggers a "send welcome email" function before redirecting him. Subsequent logins bypass this function entirely, routing him straight to the dashboard. This separation serves a critical purpose—while 99% of users interact solely with the dashboard, isolating secondary functions (like email triggers) enables independent scaling.
Though trivial in this example, the cost implications compound dramatically at scale. Each decoupled function operates on its own resource allocation curve—high-frequency features like dashboard access demand consistent infrastructure, while one-time actions (welcome emails) can scale down during inactive periods. This modular approach prevents overprovisioning for rarely triggered events, even before considering complex systems with hundreds of interdependent functions.
Where to Deploy???
Okay, so just a quick recap—we now know:
- Deploying serverless is great!
- Dividing your code into functions is modular and scalable.
- Functions can be triggered by events.
So, where do you deploy this architecture? Leading platforms like AWS Lambda, Azure Functions, and Google Cloud Functions support it, but we'll focus on Appwrite Functions.
Appwrite, an open-source Backend-as-a-Service (BaaS), bundles authentication, databases, storage, and serverless functions into a single toolkit. This tight integration streamlines deployment—instead of managing fragmented cloud services, Appwrite centralizes backend logic, letting you deploy event-driven functions with minimal overhead. For developers prioritizing simplicity without sacrificing scalability, this unified approach reduces operational friction significantly.
So, let's deploy our function!
Deploying Your First Function
Before writing code, set up your backend on Appwrite:
- Go to appwrite.io and register or log in.
- Create an organization (if new).
- Create a new project.
- Copy your Project ID for later use.
Now, let's simulate a server-side project using the node-appwrite
package:
- Create a project directory:
mkdir my-project
cd my-project
- Install the Appwrite CLI and initialize your project:
npm init -y
appwrite init
- Install dependencies:
npm install dotenv node-appwrite
- Create your function using the Appwrite CLI:
appwrite init function
For the runtime, I selected Node 20, but you can choose any runtime.
- Write your main function in
src/main.js
:
import dotenv from "dotenv";
import { Account, Client, Users } from "node-appwrite";
dotenv.config();
const client = new Client();
client.setEndpoint("https://cloud.appwrite.io/v1");
client.setProject(process.env.PROJECT_ID);
const users = new Users(client);
const account = new Account(client);
const main = async () => {
await account.create(
"test-user",
"test@test.com",
"test@123",
"test",
);
const session = await account.createEmailPasswordSession(
"test@test.com",
"test@123",
);
console.log(session);
};
main();
Add a
start
script inpackage.json
to runnode src/main.js
.Create a
.env
file with the required environment variables.
This function simulates a new user creation and login, logging the session details.
Note: Replace the email IDs with actual emails to receive the email.
Now, let's set up the function logic. Navigate to functions/your-function
where your function resides.
For this demo, we'll use Resend to send emails:
- Install the
resend
package:
npm install resend
- Update
src/main.js
with this code:
import { Resend } from 'resend';
// https://appwrite.io/docs/advanced/platform/events
export default async ({ res, req, log }) => {
const resend = new Resend(process.env.RESEND_API_KEY);
await resend.emails.send({
from: 'hello@yourdomain.com',
to: req.body.email,
subject: 'Hello!',
text: 'Hi, its nice to meet you!',
});
log('Email sent successfully');
return res.json({
success: true,
message: 'Email sent successfully',
});
};
You need to set up an account on Resend to get the API Key. Resend also requires you to connect to your own domain to send emails. You can read more about it on the Resend docs.
Now, let's push the created function to the console using:
appwrite push functions
The final step is to set up the event that connects the two pieces of code together using the users.*.create
event:
- Go to the Appwrite console and navigate to your created project.
- Navigate to the Functions tab.
- You should see your newly created function there—click on it.
- Go to its settings and under the Events section.
- Add a new event to trigger this function:
users.*.create
.
And... voila! Your program is done. If everything is set up correctly, running your main script should send the newly created user an invitation email. Try it using:
npm run start
Conclusion
In conclusion, serverless architecture is more than just a passing trend—it's a transformative approach to building and scaling modern applications.
Platforms like Appwrite further simplify the process, offering a unified backend solution that integrates seamlessly with serverless functions. Whether you're a solo developer like Bob or part of a larger team, adopting serverless can turn scalability from a daunting challenge into an effortless reflex.
Thanks for reading!
You can also connect with me here: https://www.chiragaggarwal.tech/
Top comments (4)
Mmm let's pretend for the billionth time that we're all the same as Netflix, and break down a working monolith serving a small number of users into 1000 functions, which all have to be maintained and spun up independently and which communicate with each other via rest. Won't that be fun! No downsides!
I absolutely agree! You never have to compare your projects to giants like Netflix's infrastructure. But case studying these practices help us in understanding why these extremely smart people working for these companies opt for these practices.
Ofcourse there are downsides , mainly complexity which your app might never need. But at their scale, it's a necessity.
Hope that helps!
Liked it!!! Will try it soon
Absolutely do!