Send Emails to Your Clients Almost FREE with Oracle Cloud
Surely it has happened to you sometime: you buy a domain out there, you set up your cool website and suddenly you think⊠âWhat if I could send emails to my clients?â
It is super typical when you create a Software as a Service. You put that âJoin the waiting listâ box and then you want to send an email to all the people who have signed up. Normal, right?
To be able to send bulk emails you need an SMTP server, and the truth is that it is not always easy to get it. If you set it up yourself on your own server, the IP may not have a good reputation and your emails end up straight in spam. Apart from the fact that it is a hassle to do it.
There are already services that help us with this (SendGrid, Mailgun, Amazon SES, ResendâŠ), but believe me when I tell you that they are expensive. Although it may not seem like it at first, they are. At least compared to what Iâm going to show you today.
In this post I am going to show you:
- What on earth is an SMTP server (in case you are not clear yet)
- Why popular services bleed your pocket dry
- How to get an SMTP almost for free with Oracle Cloud
- Example code so you can see how easy it is to use it
Letâs get to it!
What is an SMTP server? (Explained easily)
SMTP stands for Simple Mail Transfer Protocol.
Think of it as a âdigital postmanâ in charge of your email going from your server to the recipientâs inbox.
How does it work? Very easy:
- Connection: Your application connects to the SMTP server using a port (usually 25, 465 or 587)
- Identification: The server asks you âwho are you?â and checks that you have permission to send
- Delivery: Your app tells the server âhey, send this message to client@example.comâ and passes the content
- Distribution: The server queries the MX records of the destination domain, finds the corresponding âpostmanâ and sends the email

Basically, SMTP is like the central post office: your server puts the letter in the mailbox, and from there the SMTP protocol distributes it until it reaches the recipient.
Simple, right? Without this you cannot send emails from your application. As simple as that.
The reality of popular SMTP services
Letâs see what the best-known services offer us and why they are going to cost you an arm and a leg.
SendGrid

SendGrid is one of the best known, but its prices scale fast:
- Free: 100 emails/day
- Essentials ($19.95/month): 50,000 emails
- Pro ($89.95/month): 100,000 emails
Mailgun
Similar story with Mailgun:
- Free: 5,000 emails for 3 months, then paid
- Foundation ($35/month): 50,000 emails
- Growth ($80/month): 100,000 emails
Resend (the current favorite)

Resend is becoming very popular lately because it has a very accessible panel where you can see statistics of emails sent, recipients, and it also has a simple SDK to apply it in your projects.
Its free tier allows 3,000 free emails per month, which is quite good. But when you want to go further:
- Pro ($20/month): 50,000 emails (limited to 10 domains)
- Business ($90/month): 100,000 emails
If your current goal is only to send 3,000 emails or less per month from one email address, Resend is enough for you. You can stop reading and go to resend.com right now.
But if you plan to have much more traffic or manage sending from different email addressesâŠ
The alternative no one tells you about: Oracle Cloud SMTP
Here is where the hidden gem comes in. Oracle Cloud offers an SMTP service that is ridiculously cheap.
If you are already a follower of the blog, you will know that thanks to Oracle we have managed to have a server with 24GB of RAM and 4 cores totally free. Here is the complete tutorial.
Well Oracle Cloud offers many more things apart from VPS, and one of them is its SMTP service.

The prices you will fall in love with
Hold on tight because the price is GREAT:
- 3,000 free emails (matches Resend)
- After: $0.085 for every 1,000 emails (8 cents, about 7 euro cents)
Real price comparison
Letâs do the calculations that no one does:
| Emails/month | Resend | Oracle Cloud | Savings |
|---|---|---|---|
| 50,000 | $20 | ~$4.00 | 80% less |
| 100,000 | $90 | ~$8.25 | 91% less |
| 200,000 | $180 | ~$16.75 | 91% less |
Calculation for 50,000 emails:
- 50,000 - 3,000 (free) = 47,000 paid emails
- 47 Ă $0.085 = $3.995 â $4.00
Calculation for 100,000 emails:
- 100,000 - 3,000 (free) = 97,000 paid emails
- 97 Ă $0.085 = $8.245 â $8.25
Itâs laughable how prices are reduced. And all this without counting the additional advantages:
Advantages that Resend does not give you
- No domain limit: Resend restricts you to 10 domains on the $20 plan. Oracle has no restrictions
- Pay per real use: If one month you only send 20,000 emails, you only pay ~$1.45. In Resend you pay the entire fee
- Scalability: You can grow without brutal price jumps
The only âdisadvantageâ is that you donât have that nice Resend SDK, but later I will show you how simple it is to use a normal SMTP.
How to get your SMTP server in Oracle Cloud
Step 1: Create an account in Oracle Cloud
The first thing is to create an account in Oracle Cloud if you donât have it yet. Important tip: put real data, since at the end of the registration they will ask for card verification to confirm that the name matches yours.
Step 2: Activate the paid layer (optional but recommended)
Once the account is created, if you only want to use the free layer you wonât have to do anything else. Note: the free layer allows you to send only 100 emails a day (same as Resend).
If you want to continue without daily restrictions:
- Click âUpgradeâ in the message that appears above
- If it does not appear, search for âBillingâ in the menu
- Click âUpgrade accountâ in the âPay as you goâ section
- In a matter of minutes or hours you will receive confirmation by email
Step 3: Configure the Email Delivery service
While we wait for confirmation, we can configure:
- Search for âEmail Deliveryâ in the Oracle Cloud menu
- Create a new email configuration
- Add your domain and configure it with Cloudflare or your DNS provider
- Verify the domain following the instructions (add DNS/SPF/DKIM records)

Step 4: Get SMTP credentials
Once the domain is verified, in âConfigurationâ all the information to connect to the SMTP will appear. Save this info:
- Host:
smtp.email.region.oci.oraclecloud.com - Port: 587 (TLS) or 25
Step 5: Generate user credentials
Important: SMTP credentials do NOT match your portal access password. They are generated and shown only once, so donât lose them.
To get your SMTP password:
- Go to Identity â Domains â Default domain â Users
- Find your user and enter SMTP credentials
- Click Generate credentials
- Save the user and password that appear
The user will be a very long text string, but it is normal.

You have everything! Host, port, user, password and source email. Any external service you use and asks for SMTP information you can provide it.
Example code: How to use your SMTP in a real application
âHey Edu, Iâm a programmer and I loved Resend because it was as easy as calling their API, what do I do now with so many things?â
Relax, if you are a programmer you will know that nothing is impossible. And doing this is super easy.
I have prepared an example project in Astro (but you can adapt it to Next.js, React, Node.js, Java⊠whatever you want).
Installation of dependencies
npm install nodemailer
npm install --save-dev @types/nodemailer
Environment variables
Create your .env file with Oracle credentials:
SMTP_HOST=smtp.email.eu-frankfurt-1.oci.oraclecloud.com
SMTP_PORT=587
SMTP_USER=your_super_long_oracle_user
SMTP_PASS=your_generated_password
SMTP_FROM=noreply@yourdomain.com
Endpoint code
// src/pages/api/send-email.ts
import type { APIRoute } from 'astro';
import nodemailer from 'nodemailer';
import fs from 'fs';
import path from 'path';
interface EmailRequest {
to: string;
type: 'raw' | 'template';
message?: string;
templateData?: {
name: string;
[key: string]: any;
};
}
export const POST: APIRoute = async ({ request }) => {
try {
// Read and validate the body
const body: EmailRequest = await request.json();
// Basic validations
if (!body.type || !['raw', 'template'].includes(body.type)) {
return new Response(
JSON.stringify({ error: 'Invalid email type' }),
{ status: 400, headers: { 'Content-Type': 'application/json' } }
);
}
if (!body.to || body.to.trim() === '') {
return new Response(
JSON.stringify({ error: 'Destination email required' }),
{ status: 400, headers: { 'Content-Type': 'application/json' } }
);
}
// Read environment variables
const smtpHost = import.meta.env.SMTP_HOST;
const smtpPort = parseInt(import.meta.env.SMTP_PORT);
const smtpUser = import.meta.env.SMTP_USER;
const smtpPass = import.meta.env.SMTP_PASS;
const smtpFrom = import.meta.env.SMTP_FROM;
if (!smtpHost || !smtpPort || !smtpUser || !smtpPass || !smtpFrom) {
return new Response(
JSON.stringify({ error: 'Incomplete SMTP configuration' }),
{ status: 500, headers: { 'Content-Type': 'application/json' } }
);
}
// Create nodemailer transporter
const transporter = nodemailer.createTransporter({
host: smtpHost,
port: smtpPort,
secure: false, // true for port 465, false for others
auth: {
user: smtpUser,
pass: smtpPass,
},
});
// Prepare email content
let subject: string;
let htmlContent: string;
if (body.type === 'raw') {
if (!body.message || body.message.trim() === '') {
return new Response(
JSON.stringify({ error: 'Message required for raw email' }),
{ status: 400, headers: { 'Content-Type': 'application/json' } }
);
}
subject = 'Message from your application';
htmlContent = `<p>${body.message}</p>`;
} else { // template
subject = 'Welcome to our platform';
// Read HTML template
const templatePath = path.join(process.cwd(), 'src', 'templates', 'welcome.html');
let template = fs.readFileSync(templatePath, 'utf-8');
// Replace template variables
if (body.templateData) {
Object.keys(body.templateData).forEach(key => {
template = template.replace(`{{${key}}}`, body.templateData![key]);
});
}
htmlContent = template;
}
// Send the email
const info = await transporter.sendMail({
from: smtpFrom,
to: body.to,
subject: subject,
html: htmlContent,
});
return new Response(
JSON.stringify({
success: true,
messageId: info.messageId,
message: 'Email sent successfully'
}),
{ status: 200, headers: { 'Content-Type': 'application/json' } }
);
} catch (error) {
console.error('Error sending email:', error);
return new Response(
JSON.stringify({ error: 'Internal server error' }),
{ status: 500, headers: { 'Content-Type': 'application/json' } }
);
}
};
Example HTML Template
Create src/templates/welcome.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Welcome</title>
</head>
<body style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
<div style="background: #f8f9fa; padding: 20px; text-align: center;">
<h1 style="color: #333;">Hello {{name}}!</h1>
<p style="color: #666; font-size: 16px;">
Welcome to our platform. We are excited to have you with us.
</p>
<a href="https://yourdomain.com"
style="background: #007bff; color: white; padding: 12px 24px;
text-decoration: none; border-radius: 5px; display: inline-block;">
Start now
</a>
</div>
</body>
</html>
How to use the endpoint
// Simple email sending
const response = await fetch('/api/send-email', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
to: 'client@example.com',
type: 'raw',
message: 'Hello, this is a test message'
})
});
// Sending with template
const response = await fetch('/api/send-email', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
to: 'client@example.com',
type: 'template',
templateData: {
name: 'John Doe'
}
})
});
As you can see, sending emails with SMTP is very similar to Resend. The syntax barely changes, and you have much more control over the process.
Complete repository
I have uploaded all the example code to GitHub so you can download it and use it as a reference: View repository
VERY IMPORTANT! Do not forget to configure your .env file with the properties we have seen in Oracle, otherwise it will not be able to log in.
Conclusion: The SMTP you needed
As you can see, setting up a cheap and scalable email sending service is not complicated at all. Oracle Cloud offers you:
â 3,000 free emails to start â Ridiculous prices later (91% cheaper than the competition) â No domain limits â Pay per real use â Scalability without brutal price jumps
The only âdownsideâ is that you donât have an SDK as visual as Resend, but with the code Iâve shown you, you have everything you need.
If you want to take your automations a step further, I recommend you check out N8N, an automation tool that is revolutionizing the market. Here is the complete tutorial to install it for free.
See you in the next blog! â€ïž



What do you think?
Leave your opinion, question or suggestion. Comments are synced with GitHub Discussions .