← All articles

Where automation profiles should live, and why not beside the ones you manage

4 min read automationprofilessdk

A script that opens one browser per task creates one profile per task. Two weeks in, the profile list holds 600 entries and four of them are accounts you care about. The profiles are not the problem. Where they live is.

What a profile per task costs you

The directories are cheap. The namespace is not.

Everything that enumerates profiles walks the same list you do: the desktop app, your own tooling, the export dialog. A run that mints task-1 through task-400 puts 400 entries in front of every one of those readers, permanently, because nothing knows the run has finished.

Names also collide across runs. Last month's task-14 and this month's task-14 are the same directory, so the second run inherits the first run's cookies and identity. Sometimes that is what you want. When it is not, it shows up as an unexplained logged-in session rather than an error.

What temporary mode changes

Passing temporary: true moves the profile into a second tree. Under the cache directory, which defaults to ~/.anti-detect-browser, managed profiles live in profiles/ and temporary ones in profiles-temp/. Three things follow from that one split:

The desktop app never sees them. It reads the managed tree only, so a temporary profile is not in the list, not in search, not in the export dialog.

The two trees are separate namespaces. A temporary gmail and a managed gmail are different profiles with their own fingerprint, cookies and passkeys. Neither can overwrite the other.

The server is never asked about them. A temporary profile is local by construction, so a run cannot create cloud profiles as a side effect of starting browsers.

Set it once on the constructor, or per launch:

import { AntiDetectBrowser } from 'anti-detect-browser'

const ab = new AntiDetectBrowser({
  key: process.env.ANTI_DETECT_BROWSER_KEY,
  temporary: true,
})

for (const task of tasks) {
  const { page, browser } = await ab.launch({ profile: `task-${task.id}` })
  await page.goto(task.url)
  await browser.close()
}

Passing temporary: false on a single launch() puts that one profile back in the managed tree.

Nothing is deleted for you, deliberately

A temporary profile survives browser.close() with its fingerprint, cookies and passkeys intact. Deleting on close would be tidier, and it would also make every retry a brand new device with no history, hitting the same account from the same script. That pattern is one of the more reliable ways to get an account flagged, which is covered in why accounts still get flagged. Reuse is the feature here. The separate tree only decides who has to look at these profiles, not how long they live.

So cleanup is explicit:

const removed = ab.clearTemporaryProfiles({ olderThanDays: 7 })
console.log(`removed ${removed.length} profiles`)

or from a shell:

npx anti-detect-browser --clear-temp --older-than=7 --dry-run

The age is measured from the last time the browser engine wrote to the profile, not from when it was created, so a profile you still reuse every week is never swept. The call returns the name, directory and byte size of everything it removed, and --dry-run prints that same list without deleting. It only ever reads profiles-temp/, so a managed profile with the same name is not at risk.

One caveat worth knowing before you put this in a cron job: the method on your SDK instance skips profiles that instance currently has open, and it cannot see sessions belonging to another process. Sweep when your workers are idle, or pass the live directories in skipDirs.

When this is the wrong switch

If you run a handful of long-lived profiles that you also open by hand, keep them managed. The value here is keeping profiles out of a list, and hiding a profile you want to click on is a straight loss.

It is also mutually exclusive with cloud sync. Asking for both at once throws instead of quietly picking one, because a profile you believed was syncing and was not is a problem you find out about a month later.

And if what you actually want is a fresh identity for every run, this is the wrong tool. You would be deleting profiles constantly to get there, and you would be paying the flagging cost described above for the privilege.

Checking it yourself

Run one temporary launch, then look at both trees:

ls ~/.anti-detect-browser/profiles ~/.anti-detect-browser/profiles-temp

The new name should be in the second directory, absent from the first, and absent from the desktop app after a refresh. Then run the clear command with --dry-run and confirm the list it would delete contains nothing you recognise.

More on the SDK surface in the SDK docs, and on which parts of a profile are worth keeping in profile backup and migration.

Try it on the free tier.

Unlimited local profiles, no credit card. Check it against the detectors yourself.