Appearance
Server-side vs. pixel tracking
"Server-side tracking" and "the pixel" both end up reporting the same thing — a conversion, to Meta or Google Ads — but they get there by completely different routes, and mixing them without a plan is the single most common cause of ad accounts reporting numbers nobody trusts. This page covers how each route works, why you'd want both, and why both requires deduplication to avoid double-counting.
How a browser pixel works
A pixel is a small script — fbevents.js for Meta, Google's tag for Google Ads — loaded directly in the visitor's browser, usually from a third-party domain (connect.facebook.net and similar). When something trackable happens — a page view, a form submit — the script itself fires a request straight from the visitor's browser to the ad platform. Nothing on your server is involved; the browser is the entire delivery mechanism.
That also makes the browser the entire point of failure:
- Ad blockers and privacy extensions (uBlock Origin, Brave's built-in blocker, and similar) can stop the script from ever loading. No script, no event.
- Browser tracking prevention — Safari's ITP, Firefox's ETP — blocks or shortens the life of the cookies the pixel relies on to recognize a returning visitor, to as little as seven days.
- The signal is simply lost, not recovered later. A pixel that never fires produces no record anywhere; there's nothing downstream to reconcile against.
How server-side delivery works
Server-side delivery moves the last leg of that trip off the browser. Events still originate on your site, but instead of the browser talking to the ad platform directly, they go to a first-party endpoint you control, which then forwards them server-to-server — server to server, not browser to platform. The visitor's browser is only ever talking to your own domain; there's no third-party request for a blocker to catch, and no cross-site cookie for browser tracking prevention to restrict.
These aren't rival techniques
Server-side delivery doesn't replace on-site instrumentation — you still need something on the page (or your server logic) deciding when an event happened. What changes is the last leg: instead of the browser calling the ad platform directly, your own server does, which is the leg blockers and cookie restrictions can't touch.
Why running both causes double counting
A pixel and a server-side integration can both exist on the same site, and in fact often do — a site that has run a pixel for years frequently keeps it in place when server-side delivery gets added on top, whether on purpose or because nobody remembered it was there. If both fire for the same real-world action — one visitor filling out one form — the ad platform receives two separate reports of it, from two different paths, with no way on its own to know they're the same event. It counts both. A form-submit event that actually happened once shows up twice in the dataset.
This is worse than an inflated report. The ad platform's optimization algorithm learns from every conversion it receives — doubled counts don't just make the dashboard number wrong, they train the algorithm to chase whatever pattern produces double-fires, skewing who it shows your ad to next. See Ad blockers and iOS for how the same optimization-poisoning problem shows up on the undercounting side.
How deduplication works
The fix isn't picking one path and dropping the other — it's making sure the platform can tell when two reports describe the same event. Both copies of an event — the one from the browser and the one from the server — carry an identical event ID. When the platform receives two events with the same ID within its matching window, it keeps one and discards the other, so the conversion is counted exactly once no matter which path (or both) delivered it.
The catch is that deduplication only works when both sides are generating the same ID for the same event — which requires them to be built together, deliberately, as one integration. A separately installed legacy pixel, added at a different time by a different tool, has no way of knowing what ID a server-side system is using, and never will. That's why Meta CAPI instructs removing legacy pixel installs before connecting server-side delivery, rather than trying to reconcile the two after the fact.
How Adsidian helps
Prism's server-side delivery generates its own deduplication ID for every event it sends and doesn't depend on a separately installed pixel to work — see What is Prism? for how the pieces fit together. If a legacy pixel is still running when Prism connects, Meta CAPI walks through exactly what double counting looks like in Events Manager and where pixel code tends to be hiding, so it can be found and removed.
FAQ
Do I need a pixel at all if I'm using server-side tracking? No — Prism doesn't require one. Its own server-side delivery mints the browser identifiers it needs and reports events directly, without depending on a separately installed pixel.
If I already have a pixel installed, do I need to remove it? Yes, once server-side delivery is connected. A pixel installed separately from that integration won't share its deduplication IDs, so the platform can't tell the two reports of the same event apart and counts both. See Meta CAPI for the removal checklist.
How would I even know if I'm double counting? Numbers that look too good — a PageView or Lead count roughly double what it should be — are the usual tell. Meta CAPI covers what to check in Events Manager, and Troubleshooting covers verifying delivery more generally.
Is deduplication something I have to configure? No — it works automatically as long as every path that reports an event is using the same integration's IDs, which is the reason a standalone pixel added outside that integration can't be deduplicated against it.