In the world of cloud computing and automation, developers have a powerful tool at their disposal: the serverless function. Platforms like AWS Lambda and Google Cloud Functions revolutionized how we think about backend infrastructure, allowing us to run code without provisioning or managing servers. They are the go-to for event-driven tasks and scalable microservices.
But as our automations become more complex, evolving into sophisticated, multi-step processes we call "Agentic Workflows," a new question arises: Is a generic function the right level of abstraction?
Enter the Atomic Action.
This post will compare the familiar paradigm of serverless functions with the concept of Atomic Actions on the action.do platform. We'll explore why abstracting tasks, not just servers, is the next crucial step in building robust, scalable, and truly intelligent automations.
At its core, a serverless function is a piece of code that runs in a stateless compute container, triggered by an event. You write the code, and the cloud provider handles everything else—provisioning, scaling, and patching.
Key Characteristics:
Serverless functions are incredibly powerful. But their flexibility can also be a weakness when building highly structured, business-centric workflows. The logic of what the function does and how it connects to other tasks often lives implicitly within the code or in a separate orchestration layer, making it hard to manage and reuse at scale.
An Atomic Action, as defined on the .do platform, is the smallest, indivisible unit of work in a workflow. It’s a self-contained, executable task designed to do one thing and do it well.
Think of it not just as code, but as a formal definition of a business capability.
Actions are the fundamental building blocks of every powerful Agentic Workflow on the .do platform.
Where a serverless function is a blank canvas, an Atomic Action is a structured, reusable component with a clear purpose, defined inputs, and predictable outputs.
Let's look at a practical example. Here’s how you define an action to send a welcome email on the .do platform:
import { Action } from '@do-co/agent';
// Define a new atomic action to send a welcome email
const sendWelcomeEmail = new Action('send-welcome-email', {
title: 'Send Welcome Email',
description: 'Sends a standardized welcome email to a new user.',
input: {
to: { type: 'string', required: true },
name: { type: 'string', required: true },
},
async handler({ to, name }) {
console.log(`Sending email to ${to}...`);
// Actual email sending logic (e.g., using an SMTP service) would go here
const message = `Welcome to the platform, ${name}!`;
console.log(message);
return { success: true, messageId: `msg_${Date.now()}` };
},
});
// Execute the action with specific inputs
const result = await sendWelcomeEmail.run({
to: 'new.user@example.com',
name: 'Alex',
});
console.log(result);
Notice the difference? This isn't just a function. It's a self-documenting object with a title, description, and a strictly typed input schema. The platform understands this structure, making the action discoverable, testable, and easy to compose into larger workflows.
| Feature | Serverless Function | Atomic Action (.do) |
|---|---|---|
| Abstraction Level | Abstracts the server. | Abstracts the task or business operation. |
| Scope & Granularity | Flexible. Can be a single small task or a complex microservice. | Strict. Designed to be a single, indivisible unit of work ("atomic"). |
| Structure | Unstructured blob of code. The interface (inputs/outputs) is implicit. | Explicitly structured with a defined schema, title, and description. Self-documenting by design. |
| Reusability | Code can be reused, but the business context is often lost. | A reusable, named building block representing a specific business capability (e.g., create-invoice). |
| Composition | Requires an external orchestrator (e.g., Step Functions) to chain functions together. | Natively designed to be composed into Agentic Workflows on the .do platform. |
| Discoverability | Relies on cloud provider consoles or external documentation to find and understand. | Discoverable and manageable within the .do ecosystem, making it easy for teams to find and reuse actions. |
This isn't an "either/or" scenario. Both tools have their place in a modern developer's toolkit.
Use Serverless Functions when:
Use Atomic Actions (.do) when:
Serverless functions freed us from managing servers. Atomic Actions free us from managing the ambiguity of tasks.
By elevating the level of abstraction from a generic function to a well-defined, business-aware action, the .do platform provides the structured foundation needed for the next generation of automation. You stop writing one-off scripts and start building a library of robust, reusable capabilities.
Ready to build more powerful and manageable automations? It’s time to start thinking in actions.
What is an atomic action in the .do platform?
An atomic action is the smallest, indivisible unit of work in a workflow. It's a self-contained, executable task—like sending an email, querying a database, or calling an external API. Each action is designed to do one thing well.
How are actions different from workflows?
Actions are the individual steps, while workflows are the orchestration of multiple actions in a specific sequence or logic. You build complex workflows by composing simple, reusable actions together.
Can I create my own custom actions?
Absolutely. The .do SDK allows you to define custom actions with specific inputs, outputs, and business logic. This transforms your unique business operations into reusable, programmable building blocks for any workflow.