🚀 Executive Summary
TL;DR: Post-acquisition, integrating multiple Local Services Ads (LSA) accounts into a single lead ingestion service requires re-architecting from a “Singleton” to a “Multi-Tenant” model. Solutions range from quick service duplication to a scalable event-driven fan-out, addressing the core “Environment Variable Dependency” issue.
🎯 Key Takeaways
- The primary hurdle for integrating multiple LSA accounts is the “Singleton” trap, specifically “Environment Variable Dependency,” where services are hardcoded to a single set of OAuth credentials.
- Three architectural approaches exist: “Sidecar Duplicate” for rapid, isolated deployment; “Config Iterator” for a single service processing multiple accounts via a configuration array; and “Event-Driven Fan-Out” for highly scalable, decoupled ingestion using serverless functions and queues.
- While the “Sidecar Duplicate” offers immediate functionality and failure isolation, it increases overhead; the “Config Iterator” is more efficient but risks “Rate Limiting”; and the “Event-Driven Fan-Out” is bulletproof for scale but demands significant infrastructure changes.
Struggling to merge ad accounts after a buyout? Learn how to re-architect your backend to ingest leads from multiple Local Services Ads (LSA) profiles without duplicating your entire infrastructure.
Acquisition Survival Guide: Implementing Multiple LSA Profiles in a Single Service
I still remember the first time the CEO of TechResolve walked into the engineering pen—back when we still had a physical “pen”—at 4:00 PM on a Friday. He dropped the bomb: “We just bought out our biggest rival in the tri-state area. I want their leads flowing into our dashboard by Monday morning.”
The marketing team was popping champagne, but the engineering team was sweating bullets. Why? Because our lead ingestion service for Local Services Ads (LSA) was built with the arrogance of a startup that thought it would never need to manage more than one identity. We had hardcoded the assumption of a “Single Source of Truth.” Now, we had two sources, two sets of OAuth credentials, and one very fragile service.
If you are staring at a Jira ticket titled “Integrate Competitor LSA Accounts” and wondering how to shove two distinct Google identities into a service designed for one, you aren’t alone. Here is how we tackled it.
The Root Cause: The “Singleton” Trap
The problem isn’t usually the API itself; Google’s LSA API can handle whatever you throw at it. The problem is almost always Environment Variable Dependency.
Most DevOps pipelines inject credentials at runtime. Your deployment.yaml probably looks like this:
env:
- name: LSA_CLIENT_ID
valueFrom:
secretKeyRef:
name: prod-secrets
key: client-id
When you acquire a competitor, you suddenly have LSA_CLIENT_ID_2. But your application code—likely a Python or Node worker—is doing a process.env.LSA_CLIENT_ID call. It expects one identity. To fix this, you have to move from a Singleton architecture to a Multi-Tenant one.
Here are three ways to solve this, ranging from “quick and dirty” to “architecturally pure.”
Solution 1: The “Sidecar” Duplicate (The Quick Fix)
If the business needs this working yesterday and you don’t have the dev cycles to refactor the codebase, do not be ashamed to use the brute-force method. Clone the deployment.
Instead of trying to make one service handle two accounts, you spin up a second instance of the service specifically for the acquired company. You simply map different secrets to the standard environment variable names.
Pro Tip: This increases your compute costs and management overhead, but it isolates failure domains. If the competitor’s credentials expire, it won’t crash your main lead pipeline.
The Implementation:
# docker-compose.yml (or k8s equivalent)
services:
lsa-ingest-legacy:
image: techresolve/lsa-worker:v2.4
environment:
- CLIENT_ID=${OUR_ID}
- TENANT_TAG=legacy
lsa-ingest-acquired:
image: techresolve/lsa-worker:v2.4
environment:
- CLIENT_ID=${COMPETITOR_ID}
- TENANT_TAG=acquired
This is hacky, but it works instantly. The downside? You are now maintaining two stacks for the same logic.
Solution 2: The Config Iterator (The Developer’s Fix)
This is the middle ground. You refactor the application to accept a JSON array of credentials rather than a single string. This allows a single service instance to loop through multiple accounts, fetch leads from all of them, and dump them into your database.
You move your configuration from simple Key-Value pairs to a mounted configuration file (ConfigMap in Kubernetes terms).
The Logic Change:
# pseudo-code for the worker
def fetch_leads():
accounts = load_config("lsa_accounts.json")
for account in accounts:
try:
client = auth_google(account['client_id'], account['refresh_token'])
leads = client.get_leads()
database.insert(leads, source=account['brand_name'])
except AuthError:
log.error(f"Failed to auth for {account['brand_name']}")
# Critical: Ensure one failure doesn't stop the loop!
continue
This keeps your infrastructure footprint small, but beware of Rate Limiting. If you run both accounts in one thread/process, you risk hitting API quotas shared across the instance IP or getting throttled if the code isn’t async.
Solution 3: The Event-Driven Fan-Out (The ‘Nuclear’ Option)
If you are looking for the “Cloud Architect” solution that will scale when you acquire your next three competitors, you stop polling directly from the monolith.
You move the LSA authentication logic into ephemeral functions (like AWS Lambda or Azure Functions). You trigger a function for each account, which then pushes the data into a shared queue (SQS/RabbitMQ). Your main service then just processes the queue, not caring where the lead came from.
| Component | Role |
| Cloud Scheduler | Triggers an event every 5 minutes with a payload: { "account_id": "123" }. |
| Serverless Function | Receives ID, fetches creds from Vault, calls Google LSA API, pushes result to Queue. |
| Core Service | Listens to prod-leads-queue. It is now completely agnostic of Google credentials. |
I call this the ‘Nuclear’ option because it requires significant infrastructure changes (Terraform, IAM roles, Queue setup), but it is bulletproof. If the acquired company’s token is revoked, that specific Lambda fails, errors are logged to Dead Letter Queues, and your main business runs uninterrupted.
My Recommendation
For this week? Do Solution 1. Get the data flowing and keep the CEO happy. Then, create a tech-debt ticket for next sprint to implement Solution 2. Only jump to Solution 3 if you plan on becoming a holding company that acquires businesses monthly.
🤖 Frequently Asked Questions
âť“ What is the root cause of issues when integrating multiple LSA accounts into a single service?
The root cause is typically the “Singleton” trap, specifically “Environment Variable Dependency,” where the application is designed to process only one set of OAuth credentials injected at runtime.
âť“ How does the “Config Iterator” solution address the integration of multiple LSA accounts compared to the “Sidecar Duplicate”?
The “Config Iterator” refactors a single service to ingest a JSON array of credentials, allowing it to loop through multiple accounts, reducing infrastructure footprint. The “Sidecar Duplicate” involves cloning the entire service for each account, increasing compute costs but isolating failure domains.
âť“ What is a critical consideration when implementing the “Config Iterator” solution for multiple LSA accounts?
A critical consideration is “Rate Limiting.” Running multiple accounts in a single thread/process risks hitting API quotas or getting throttled if the code isn’t designed for asynchronous operations or distributed processing.
Leave a Reply