The Dev Log › AI & Machine Learning
Adding AI Features to Your SaaS Responsibly: Cost, Latency, Privacy and UX
By Jezer Niel Blanca, Full Stack Developer ·
·
6 min read
A practical guide to adding AI to an existing product without surprise bills, slow pages or privacy problems, with Laravel patterns for caching, rate limits and queues.
Almost every SaaS product is being asked the same question right now: where's the AI? Adding an AI feature has never been easier technically. Adding one responsibly is a different matter. A careless integration can quietly run up costs, slow down your app, send customer data somewhere it shouldn't go, and frustrate users with confident wrong answers. In this post I'll walk through how I approach adding AI features to an existing product, covering the things that matter most: choosing the right feature, cost, latency, privacy and user experience, with Laravel patterns for each.
Start With a Problem, Not a Model
The worst AI features are the ones added because a competitor has one. The best ones remove a specific, recurring chore for users. Before writing any code, I look for tasks that are:
- Repetitive, like summarising long threads or categorising incoming items.
- Tolerant of imperfection, where a draft that a human reviews is still valuable.
- Text-heavy, since language models are strongest with language.
- Easy to verify, so users can quickly tell whether the output is right.
Good first features tend to be drafts, summaries, suggestions, classification and search. Risky first features are anything that acts automatically on money, legal matters or health information without human review.
Define What Success Looks Like
Decide up front how you'll know the feature is working. Are users accepting suggestions or editing them heavily? Are they using it more than once? Without a measure, you can't tell whether it's helping or just adding cost.
Control Cost Before It Controls You
AI APIs usually charge per token, which means cost grows with usage in a way traditional features don't. A feature that's cheap for ten users can be expensive for ten thousand. These are the controls I put in place from the start.
Cache Identical Requests
If the same input produces the same useful output, don't pay for it twice. Hash the input and cache the result:
use Illuminate\Support\Facades\Cache;
public function summarise(string $text): string
{
$key = 'ai-summary:'.hash('sha256', $text);
return Cache::remember($key, now()->addDays(7), fn () => $this->client->chat([
['role' => 'system', 'content' => 'Summarise the text in three short bullet points.'],
['role' => 'user', 'content' => $text],
]));
}
Limit Usage Per User or Team
Rate limits protect both your budget and fairness between customers. Laravel's RateLimiter makes per-user limits simple:
use Illuminate\Support\Facades\RateLimiter;
$allowed = RateLimiter::attempt(
key: 'ai-summary:'.$user->id,
maxAttempts: 30,
callback: fn () => true,
decaySeconds: 3600,
);
if (! $allowed) {
return back()->with('error', 'You have reached the hourly limit for summaries.');
}
A few more cost habits:
- Choose the smallest model that does the job well. Test cheaper models first.
- Trim inputs. Send only the relevant part of a document, not the whole thing.
- Cap output length with the provider's max tokens setting.
- Track usage per team so you can spot heavy users and price plans sensibly.
Put a limit on every AI feature before launch. It's much easier to raise a limit for happy customers than to explain a surprise bill.
Keep the App Fast
Language model calls can take several seconds, which feels slow inside a normal web request. Never let an AI call block something the user needs right now.
Move Slow Work to Queues
For anything that doesn't need an instant answer, like summarising a new document or tagging uploaded items, dispatch a job and update the UI when it's done:
<?php
namespace App\Jobs;
use App\Ai\Summariser;
use App\Models\Document;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
class SummariseDocument implements ShouldQueue
{
use Queueable;
public int $tries = 3;
public int $timeout = 60;
public function __construct(public Document $document) {}
public function handle(Summariser $summariser): void
{
$this->document->update([
'summary' => $summariser->summarise($this->document->body),
'summarised_at' => now(),
]);
}
}
The page can show a subtle "summary in progress" state and poll for the result, so the user keeps working while it runs.
Stream Interactive Responses
For chat-style features where the user is waiting, streaming the response token by token makes a big difference to perceived speed. Users see output starting almost immediately instead of staring at a spinner.
Fail Gracefully
Providers have outages and slow periods. Set timeouts on every call, retry sensibly, and make sure the rest of the page works when the AI part doesn't. The feature should degrade to "not available right now," never to a broken screen.
Protect Customer Data
Privacy is where responsible AI features differ most from reckless ones. Your customers trusted you with their data, not every third-party service you might call.
- Read your provider's data terms. Understand whether inputs are stored, for how long, and whether they're used for training. Choose settings and plans that match your obligations.
- Send the minimum. Strip names, emails, phone numbers and IDs when the task doesn't need them.
- Never send secrets. Passwords, API keys and payment details should never appear in a prompt.
- Respect tenancy. In a multi-tenant app, make sure one customer's data can never end up in another customer's prompt or context.
- Update your privacy policy and, where required, your data processing agreements to mention the AI provider.
Let Customers Opt Out
For B2B products especially, some customers will want AI features switched off for their workspace. A feature flag per team makes that simple. If you use Laravel Pennant, you can define a flag that checks a team setting and gate the feature with Feature::active('ai-summaries'), which also lets you roll out gradually to a few teams first.
Design the UX for Imperfect Output
Even the best models are sometimes wrong. Good AI UX accepts that and designs around it.
- Make AI output editable. Present drafts and suggestions, not final decisions.
- Label it clearly. Users should know when content was generated.
- Show the source when summarising or answering from documents, so users can check.
- Collect feedback with a simple thumbs up or down. It tells you where the feature struggles.
- Keep the human in control for anything that sends, deletes, pays or publishes.
Don't Hide Existing Workflows
An AI shortcut should sit alongside the normal way of doing things, not replace it. If the suggestion is wrong, the user must still be able to do the task manually without friction.
Wrapping up
Adding AI to an existing SaaS responsibly means picking a real problem, putting cost controls like caching and rate limits in place before launch, keeping the app fast with queues and streaming, protecting customer data with minimal inputs and clear terms, and designing UX that treats output as a draft. Get those right and AI becomes a feature customers value instead of a risk. If you'd like to add AI to your product the careful way, I'd love to build it with you and my team.
Tags: AI, SaaS, Laravel, Product