web sdk performance guide - Genetec/DAP GitHub Wiki

Optimizing Web SDK performance

This guide provides strategies for optimizing your Web SDK integration. Following these recommendations will improve response times, reduce server load, and create a more efficient application.

Response format optimization

Use JSON format

Always use text/json for optimal performance.

The Web SDK supports both JSON and XML, but JSON provides significantly better performance:

Format Accept Header Performance Impact
JSON text/json Fastest - Recommended
JSON (legacy) application/jsonrequest Slower - For SC 5.7 compatibility
XML text/xml Slower - Only when required
XML (legacy) application/xml Slower - For SC 5.7 compatibility
Default */* Slowest - Uses XML

Example:

GET /entity?q=entity={guid},Name,Description
Accept: text/json

Performance gain: JSON responses are typically 30-40% smaller and parse faster than XML.

Field projection

Request only what you need

Problem: Retrieving all entity properties wastes bandwidth and processing time.

Solution: Use field projection to specify exactly which properties you need.

Comparison

Inefficient (retrieves all properties):

GET /entity/{cardholder-guid}

Efficient (retrieves only needed properties):

GET /entity?q=entity={cardholder-guid},FirstName,LastName,EmailAddress,MobilePhoneNumber

Response:

{
  "Rsp": {
    "Status": "Ok",
    "Result": {
      "FirstName": "Patricia",
      "LastName": "Lynch",
      "EmailAddress": "[email protected]",
      "MobilePhoneNumber": "995-870-2733"
    }
  }
}

Requesting only the fields you need can greatly reduce response size.

When to use full entity retrieval

Use /entity/{guid} only when:

  • You need all properties
  • Exploring entity structure during development
  • Creating complete backups

Batch operations

Read multiple entities in one request

Problem: Making separate requests for each entity causes network overhead.

Solution: Batch multiple entity queries into a single request.

Reading multiple entities

Inefficient (3 separate requests):

GET /entity?q=entity={cardholder1},FirstName,LastName
GET /entity?q=entity={cardholder2},FirstName,LastName
GET /entity?q=entity={cardholder3},FirstName,LastName

Efficient (1 batched request):

GET /entity?q=entity={cardholder1},FirstName,LastName,entity={cardholder2},FirstName,LastName,entity={cardholder3},FirstName,LastName

Response:

{
  "Rsp": {
    "Status": "Ok",
    "Result": [
      {
        "FirstName": "Patricia",
        "LastName": "Lynch"
      },
      {
        "FirstName": "Carson",
        "LastName": "Jones"
      },
      {
        "FirstName": "Philip",
        "LastName": "Weissnat"
      }
    ]
  }
}

This reduces the number of HTTP requests from three to one.

Batch different entity types

You can query different entity types in the same request:

GET /entity?q=entity={cardholder},FirstName,LastName,EmailAddress,entity={credential},Name,ActivationDate,State

Response:

{
  "Rsp": {
    "Status": "Ok",
    "Result": [
      {
        "FirstName": "Adrienne",
        "LastName": "Rowe",
        "EmailAddress": "[email protected]"
      },
      {
        "Name": "Adrienne Rowe Credential",
        "ActivationDate": "2023-07-15T04:31:00.307Z",
        "State": "Active"
      }
    ]
  }
}

Updating multiple entities

Efficient batch update:

POST /entity?q=entity={cardholder1},[email protected],entity={cardholder2},[email protected],entity={cardholder3},[email protected]

Benefits:

  • Reduces network overhead
  • Minimizes latency
  • Improves server resource utilization
  • Reduces serialization overhead
  • Increases throughput

Calling the same method multiple times

You can call the same method multiple times on one entity in a single request. These two forms are equivalent:

POST /entity?q=entity={partition-guid},AddMember({entity-guid-1}),AddMember({entity-guid-2}),AddMember({entity-guid-3})
POST /entity?q=entity={partition-guid},AddMember({entity-guid-1}),entity={partition-guid},AddMember({entity-guid-2}),entity={partition-guid},AddMember({entity-guid-3})

Both produce the same result. The first form is shorter because it chains method calls on the same entity without repeating entity=. Calls are processed in order, which matters when operations depend on each other.

Limitation: Query string length limits.

Session management

Understanding and optimizing session management is critical for Web SDK performance. For detailed session architecture and authentication, see the Getting Started Guide.

How sessions work

When you make your first authenticated request, the Web SDK creates a session that:

  • Establishes a connection to Security Center
  • Caches queried entities in memory
  • Stores session-specific settings (like /creationpartition)
  • Tracks event subscriptions

Session lifecycle

Event Behavior
First authenticated request Session is created
Any API call Resets the inactivity timer
5 minutes of inactivity Session expires
Active event subscription Keeps the session active while the subscription remains open

Session behavior in practice

  • If a session expires, the next authenticated request creates a new session.
  • Session-scoped settings (for example /creationpartition) do not carry over to a new session.
  • Event subscriptions must be recreated after session expiration or reconnect.
  • For short-lived scripts, creating a new session per run is normal.

Keeping the session alive

To prevent session expiration during idle periods, send a request to the base URL at an interval shorter than the 5-minute timeout:

GET /

This resets the inactivity timer without adding meaningful load.

If your application uses event subscriptions, the open connection already keeps the session active. No additional keep-alive is needed while a subscription is open.

Session isolation

Recommendation: Use one Security Center user account per application.

Why:

  • Sessions are shared when the same credentials and application ID are used, which avoids duplicate caches

Example architecture:

Application A → [email protected] → Session A → Cache A
Application B → [email protected] → Session B → Cache B
Application C → [email protected] → Session C → Cache C

Session-specific settings

Critical: Some settings are session-scoped and lost when sessions expire:

  • /creationpartition/{partitionIds} - Default partition for entity creation
  • Entity cache contents
  • Event subscriptions

Best practice:

  • Call /creationpartition before creating entities (don't assume it persists)
  • Re-subscribe to events if session was recreated
  • Implement session detection in your application

Cache strategies

The Web SDK maintains an in-memory entity cache per session. Understanding and leveraging this cache is crucial for performance.

How the cache works

First request for an entity:

  1. Web SDK receives request
  2. Queries Security Center Directory
  3. Loads entity data
  4. Stores in cache
  5. Returns to client

Subsequent requests for same entity (cache hit):

  1. Web SDK receives request
  2. Returns from cache
  3. No Directory query needed

Using DownloadAllRelatedData

Use DownloadAllRelatedData=true when you want the report to load the full data for the entities it returns:

GET /report/CardholderConfiguration?q=DownloadAllRelatedData=true,Page=1,PageSize=1000

This applies to the entities returned by the report. Related entities linked to those results can also be loaded, depending on the entity type, but you should not assume they are loaded with the same level of detail. If you need data from a related entity, query that entity directly.

If you need the returned GUIDs to match the filter exactly, also use StrictResults=true.

Example workflow:

# Step 1: Run the report and load the full data for the returned cardholders
GET /report/CardholderConfiguration?q=DownloadAllRelatedData=true,Page=1,PageSize=1000

# Step 2: Query specific cardholders
GET /entity?q=entity={cardholder1},FirstName,LastName,entity={cardholder2},FirstName,LastName

When to use DownloadAllRelatedData

Use when:

  • Bulk operations on many entities
  • Exporting data
  • Generating reports
  • Processing large batches

Don't use when:

  • Querying single entities
  • Only need GUID list (not full entity data)
  • Memory constrained environments
  • Session likely to expire before using cached data

Cache scope

What's cached per session:

  • Entity data loaded via /entity queries
  • Entities loaded via DownloadAllRelatedData=true
  • Related entities automatically loaded with main entity

What's NOT cached:

  • Report results (/report endpoints)
  • Event stream data

Basic entity properties

If you only need basic entity information, don't use DownloadAllRelatedData=true:

Basic properties available without full entity load:

  • Guid
  • Name
  • Description
  • EntityType
  • LogicalId
  • CreatedOn
  • IsOnline
  • CustomFields (metadata only)

Example (efficient for basic info):

GET /report/CardholderConfiguration?q=Page=1,PageSize=100
# Returns GUIDs only, no full entity data loaded

Pagination best practices

Use pagination for queries that return large result sets.

Pagination parameters

GET /report/{reportType}?q=Page={page},PageSize={pageSize}
  • Page - Page number (starts at 1)
  • PageSize - Results per page

Pagination detection

The Web SDK uses a PageSize + 1 pattern to indicate more results:

More pages available:

{
  "Rsp": {
    "Status": "TooManyResults",
    "Result": [
      /* PageSize + 1 entities */
    ]
  }
}

Last page:

{
  "Rsp": {
    "Status": "Ok",
    "Result": [
      /* PageSize or fewer entities */
    ]
  }
}

Choosing a page size

There is no single recommended page size that fits every deployment.

Start with a conservative value, then increase it based on observed behavior in your environment.

Factors affecting page size:

  • Network bandwidth
  • Memory constraints
  • Processing time requirements
  • Entity payload complexity

Pagination with cache warming

Combine pagination with DownloadAllRelatedData for optimal bulk processing:

GET /report/CardholderConfiguration?q=Page=1,PageSize=1000,DownloadAllRelatedData=true

Result:

  • Returns 1000 cardholder GUIDs (or PageSize + 1 if more exist)
  • Loads complete data for all 1000 cardholders into cache
  • Subsequent entity queries are served from cache

Endpoints supporting pagination:

  • /report/EntityConfiguration
  • /report/CardholderConfiguration
  • /report/CredentialConfiguration
  • /report/UserReport
  • /report/UserGroupReport
  • /report/AccessRuleConfiguration

Query optimization

Use specific filters

If a report exposes filters for the data you need, include them in the request instead of retrieving a broader result set and filtering it in your application.

You can combine multiple filters in the same request. Filters use AND logic.

Example:

GET /report/CardholderConfiguration?q=FirstName=John,FirstNameSearchMode=Contains,AccessStatus@Active,Page=1,PageSize=100

Result: Only active cardholders with "John" in first name.

See also