Scaling Browser Contexts with Per-Context Profiles
Plan profile-backed browser capacity with measured workloads, bounded queues, clean lifecycles, and explicit isolation requirements.
Prefer the maintained product doc?
This article has a matching page in the docs center. Use the docs for the canonical setup flow, current flags, and long-term reference.
Capacity starts with the workload
Browser capacity is a property of a workload on a particular host. A simple navigation, a media application, a document renderer, and a long-running dashboard can place very different demands on the same browser release. A concurrency figure copied from another deployment says little unless the pages, actions, network conditions, graphics path, storage policy, and completion criteria also match.
Per-context profiles let authorized sessions keep separate profile, storage, locale, and route assignments while sharing selected browser resources. This can reduce repeated overhead, but it does not make pages free. Active documents, media, downloads, workers, screenshots, and application scripts still consume CPU, memory, network capacity, and file handles.
Plan from measured work rather than a promised context count. Define a representative job, run it on the target image, observe steady and peak resource use, and establish a limit that leaves recovery headroom. Revisit the limit whenever the browser release, host class, page mix, or operational policy changes.
Choose the isolation boundary
Start by deciding what must be isolated. A browser context can provide a separate storage partition and a separate approved identity assignment within shared browser infrastructure. That model suits many test tenants, regional compatibility sessions, and independent application accounts when the service owner has authorized the work.
A context is not a separate operating-system process boundary. Use separate browser instances when a workload needs independent process privileges, strict resource containment, different extension sets, separate crash domains, or a security policy that forbids shared browser infrastructure. Use separate hosts or containers when the boundary must include the operating system and network namespace.
Write the boundary decision into the service design. A scheduler should know whether a job may share a browser, must use a dedicated browser instance, or requires a dedicated worker. Avoid letting individual callers choose a cheaper boundary without policy review. Capacity pressure should never weaken an approved isolation requirement.
Each context needs one identity assignment for its entire lifetime. Attach the approved profile, storage policy, route policy, locale policy, and workload owner before the first page or background task begins. If the identity plan changes, close the context and create a new assignment. Mid-session identity changes make results difficult to interpret and can join activity that policy intended to keep separate.
Define a representative job
A useful benchmark begins with an application transaction, not an empty browser. Select pages and actions that reflect ordinary production work. Include login only when the account owner has authorized it and the credentials can be protected. Include media, downloads, screenshots, document generation, or background activity when those features appear in normal jobs.
Describe the job in operational terms: arrival, navigation, work, completion, and cleanup. State the maximum acceptable duration, success condition, retry policy, and storage disposition. This gives the benchmark a result that the scheduler can understand. It also prevents a fast but incomplete run from appearing better than a correct one.
Use the production browser build, deployment image, host class, graphics configuration, extensions, and network class. A benchmark on a developer laptop can help find obvious issues, but it cannot approve a production limit for a different environment. Virtualization and container settings also affect memory pressure, shared storage, graphics access, and process limits.
Warm-up policy must match production. If workers stay warm between jobs, measure both startup and warm operation. If policy requires a new browser for every group of jobs, include startup and shutdown in the result. Cache state, persistent storage, and connection reuse should follow the same rules as the service.
Create more than one representative job when the workload has distinct classes. A lightweight status check and a rendering-heavy report should not share one average cost. The scheduler can assign separate limits or queues to each class and prevent expensive work from consuming all available capacity.
Measure the full lifecycle
Observe browser startup, context creation, page activity, idle periods, context close, and browser shutdown. Resource peaks often occur during navigation, decoding, screenshots, or cleanup rather than at steady state. A benchmark that samples only after the page settles can miss the condition that actually limits throughput.
Track host memory, available memory, CPU saturation, storage activity, network use, open files, job duration, queue delay, success rate, context creation time, and context close time. Together, these measurements show whether the service can complete authorized work while retaining enough headroom to recover.
Measure completed jobs per observation window, not just simultaneous contexts. A high concurrency setting can reduce throughput when jobs compete for CPU, memory bandwidth, network capacity, or a shared upstream service. The preferred operating point is the one that completes work predictably within service objectives, not the one that keeps the largest number of contexts open.
Include failure cleanup in the measurement. Cancel a job at controlled points, trigger the normal timeout path, and confirm that pages, contexts, storage handles, and scheduler leases are released. A service that succeeds only on the happy path will gradually lose capacity during real incidents.
Run the benchmark long enough to expose accumulation. Memory that returns after each job is different from memory that rises across the entire run. Context close time that increases gradually can indicate pending work or overloaded cleanup. Use the trend to define an observation trigger and investigate before raising limits.
Establish a safe operating limit
Increase load in controlled steps. Hold each step until the workload reaches a stable pattern, then compare completed work, latency, error rate, and resource headroom with the previous step. Stop when service objectives begin to degrade or recovery headroom becomes too small. The approved limit should remain below that point.
Reserve capacity for variation. Production pages change, network requests arrive in bursts, media sizes differ, and neighboring services may use the same host. A limit taken directly from the highest successful benchmark leaves no room for those changes. Choose a lower operating limit and define an emergency condition that stops admission before the host becomes unresponsive.
Document what the limit covers. Record the browser release, deployment image, host class, representative job versions, observation period, network class, and approval date. A bare concurrency number loses meaning as soon as someone changes the environment.
Use separate limits for browser groups and host groups when needed. A warm browser can accept only the number of contexts supported by its measured workload. A host can accept only the number of browser groups that fit its resource and isolation policy. Both limits matter, and either one can apply backpressure.
Review the limit after any material change. Browser upgrades, operating-system updates, graphics drivers, extensions, page redesigns, new media behavior, storage changes, proxy policy, and host resizing can all affect capacity. A short revalidation is cheaper than discovering during an incident that the old baseline no longer applies.
Apply backpressure at admission
An unbounded queue moves overload out of sight but does not remove it. Set a maximum queue age and a maximum amount of accepted work. Reject or defer requests when the service cannot start them within the agreed window. Callers then receive a clear capacity response instead of waiting behind work that may never complete.
Use a lease for every admitted job. The lease ties a queue item to a browser group, context assignment, owner, and deadline. Release it only after cleanup finishes. If a worker disappears, lease expiry lets the scheduler recover the assignment through a controlled reconciliation path.
Admission should consider workload class. Expensive jobs may need their own pool or a weighted limit. Small jobs should not be permanently blocked by a continuous stream of large work, and large jobs should not be split into unsupported partial sessions merely to fit an available slot.
Pace creation rather than opening every admitted context at once. Initialization can create a short resource spike even when the steady workload fits. A scheduler can start work gradually, watch health signals, and pause admission when startup latency or memory pressure rises.
Retries need the same admission controls as new work. Immediate retries can multiply load during an upstream outage or a browser issue. Use bounded attempts, a delay policy, and a final failure state. Preserve the original identity assignment when the authorized session must remain continuous, and start a new assignment only when policy requires a new session.
Keep lifecycle ownership explicit
One service should own each browser group from start to finish. It creates the browser under an approved release and policy, admits contexts, tracks leases, closes completed work, drains the group for maintenance, and shuts it down. Split ownership makes it easy for contexts to survive after the scheduler believes they are gone.
Define context states such as pending, starting, active, closing, and closed. State transitions should be idempotent so a repeated close request remains safe. A context that misses its close deadline should move to reconciliation and stop receiving new work.
Close the page and context through the supported application path. Wait for completion before releasing the slot. If close cannot complete within the measured deadline, drain the entire browser group and replace it according to policy. Do not keep admitting work to a group with uncertain resource ownership.
Drain before deployment changes. Stop admission, allow active jobs to finish within their deadlines, close remaining contexts through the cancellation policy, and confirm that leases are released. Then update or replace the browser group. This preserves audit history and avoids mixing releases inside one operational unit.
Set a maximum group lifetime based on observed stability and maintenance needs. Time alone should not interrupt a valid session. Drain at a session boundary, and coordinate persistent storage according to its retention policy. The purpose is predictable maintenance, not arbitrary identity rotation.
Protect profile and storage separation
The scheduler should allocate only profiles approved for the workload, browser release, and regional policy. It should never substitute an unrelated profile because the requested item is busy or unavailable. Return a clear assignment failure and let the caller or owner decide whether another approved identity may be used.
Persistent storage stays attached to one identity record. Ephemeral storage is removed after the session according to policy. Do not mount one storage location into two active contexts, and do not attach old storage to a new profile assignment. Storage mistakes can cross privacy boundaries even when the contexts themselves are separate.
Route assignments follow the same ownership model. Bind the approved route policy before work begins. If a route fails, retries should remain inside the allowed network policy. A change that alters the intended regional identity should occur through a new session assignment.
Keep credentials outside profile packages and scheduler logs. Workers should receive the minimum secret access needed for their assigned job. Redact route credentials, page data, and account identifiers from metrics. Capacity dashboards need resource and lifecycle information, not private session contents.
Monitor service health
Build dashboards around user-visible work and recovery. Track queue age, admitted jobs, active jobs, completions, failures by operational category, retries, cancellation time, context close time, browser group replacements, memory headroom, CPU pressure, and host availability.
Alert on trends rather than isolated peaks where possible. A steady rise in close time, queue age, or residual memory is more useful than a single short spike. Pair alerts with a runbook that says when to pause admission, drain a browser group, remove a host from service, or roll back a release.
Distinguish application failures from capacity failures. A page validation failure may occur with ample host resources. A capacity failure may affect otherwise healthy jobs across several workloads. Clear categories prevent operators from raising limits to solve an application issue or changing page logic to solve host pressure.
Use logs with stable job, context, browser-group, and host references. Redact profile contents, credentials, and customer page content. Keep any additional evidence in an access-controlled incident record with a short retention period.
Review abandoned resources regularly. Compare scheduler leases with active contexts and browser groups. Reconcile differences through the supported shutdown path. This catches lost ownership before it becomes a large capacity leak.
Recover from overload
The first response to sustained overload is to stop admission. Continuing to create work while the host is struggling increases cleanup time and can make healthy sessions fail. Preserve active jobs that remain inside their service deadlines, and cancel the rest according to policy.
Drain the most affected browser group when pressure is localized. If host health continues to decline, remove the host from scheduling and let the supervisor replace its groups. Keep recovery actions bounded so every operator and automation component makes the same decision from the same signal.
After recovery, do not immediately restore the previous limit. Start below the approved operating point, confirm that cleanup completed, and inspect queue and host trends. If the event followed a release or workload change, rerun the representative benchmark before returning to normal capacity.
Preserve enough evidence to explain the event without retaining private page data. Timeline, host metrics, queue state, lifecycle events, release version, and workload class are usually sufficient for capacity analysis. Sensitive traces should be collected only when necessary and handled under the evidence policy.
Plan releases and rollbacks
Treat capacity as part of release acceptance. Run the representative workload on the candidate browser and deployment image. Compare completion rate, latency distribution, resource headroom, creation time, and cleanup with the approved baseline. Investigate material changes before promotion.
Roll out to a limited deployment group first. Keep the previous approved image available and preserve scheduler compatibility with both groups during the observation period. If rollback is required, drain candidate groups and restore the complete previous pairing. Avoid changing browser binaries underneath active contexts.
Capacity changes need approval just like code changes. Record the evidence, reviewer, new limit, affected workload classes, and rollback condition. A limit raised without workload evidence can turn a small regression into a host-wide incident.
Practical review checklist
Before production use, confirm the following:
- Every workload class has a representative job and a clear completion condition.
- Isolation requirements state whether contexts, browser instances, or hosts are required.
- Capacity was measured on the target release, image, and host class.
- The approved limit retains recovery headroom.
- Admission, queue age, retries, and creation rate are bounded.
- Every context has one profile, storage, route, owner, and lifecycle record.
- Cleanup finishes before capacity returns to the scheduler.
- Persistent storage never crosses identity assignments.
- Dashboards omit credentials, profile contents, and private page data.
- Deployment groups can drain and roll back without interrupting unrelated work.
During operation, review throughput, queue delay, cleanup trends, group replacement frequency, and host headroom. When those values move away from the baseline, reduce admission and investigate before increasing capacity.
Selecting a deployment model
Per-context profiles are appropriate when the workload needs identity and storage separation and its policy permits shared browser infrastructure. Separate browser instances are appropriate when process-level security, resource, extension, or failure boundaries matter. Separate workers are appropriate when isolation must include the operating system or network namespace.
No single model is best for every job. A production service may use all three: lightweight authorized tests in per-context groups, sensitive application sessions in dedicated browser instances, and high-assurance workloads on dedicated workers. Keep each choice explicit in scheduler policy.
BotBrowser Per-Context Fingerprint is available on the applicable enterprise plan. Use the maintained Per-Context documentation for supported setup and entitlement details. The performance guide covers host measurements, and profile management covers assignment ownership. Review plans when selecting a production deployment model.
Related Articles
Take BotBrowser from research to production
The guides cover the model first, then move into cross-platform validation, isolated contexts, and scale-ready browser deployment.