Last updated: 2026-04-06
Reference
API Performance Optimization¶
Optimize your Dxtra API integration for production performance and scalability.
Response Time Guidelines¶
Typical response times for well-optimized queries:
| Operation | Target | Notes |
|---|---|---|
| GraphQL queries | < 200ms | Simple queries with limited fields |
| Mutations | < 500ms | Single-record operations |
| Batch operations | < 2s | Up to 100 records |
Performance Variability
Actual response times depend on query complexity, data volume, and network conditions. Complex nested queries or large result sets may take longer.
Query Optimization¶
Request Only Needed Fields¶
GraphQL
# Avoid: Overfetching data
query GetDataSubjects {
dataSubjects {
id
did
createdAt
updatedAt
dataProcessingActivities {
id
typeId
triggeredAt
fieldIds
preferenceIds
}
}
}
# Better: Request only needed fields with limits
query GetDataSubjectsOptimal {
dataSubjects {
id
did
dataProcessingActivities(limit: 1, order_by: {triggeredAt: desc}) {
typeId
triggeredAt
}
}
}
Caching Strategy¶
Implement caching for frequently accessed reference data:
JavaScript
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
const getCachedDataControllers = async () => {
const cacheKey = 'dataControllers';
const cached = cache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
return cached.data;
}
const fresh = await client.request(GET_DATA_CONTROLLERS);
cache.set(cacheKey, {
data: fresh,
timestamp: Date.now()
});
return fresh;
};
Batch Processing¶
JavaScript
// Avoid: Sequential API calls
const processSubjects = async (subjects) => {
const results = [];
for (const subject of subjects) {
const result = await processDataSubject(subject);
results.push(result);
}
return results;
};
// Better: Use batch mutations
const processBatchSubjects = async (subjects) => {
const mutation = `
mutation ProcessBatch($objects: [dataSubjects_insert_input!]!) {
insert_dataSubjects(objects: $objects) {
returning {
id
did
}
}
}
`;
return client.request(mutation, { objects: subjects });
};
Connection Management¶
Reuse Client Instances¶
JavaScript
class DXTRAClient {
constructor(jwt) {
this.client = new GraphQLClient('https://api.dxtra.ai/v1/graphql', {
headers: {
'Authorization': `Bearer ${jwt}`,
'X-Hasura-Role': 'user'
},
keepAlive: true,
timeout: 30000
});
}
async healthCheck() {
return this.client.request('{ __typename }');
}
}
Pagination¶
Use offset-based pagination for large datasets:
GraphQL
query GetDataSubjectsPaginated($offset: Int = 0, $limit: Int = 50) {
dataSubjects(
offset: $offset
limit: $limit
order_by: { createdAt: asc }
) {
id
did
createdAt
}
dataSubjectsAggregate {
aggregate {
count
}
}
}
Performance Monitoring¶
Request Timing¶
JavaScript
const performanceWrapper = async (operation, query, variables) => {
const start = Date.now();
try {
const result = await client.request(query, variables);
const duration = Date.now() - start;
console.log(`${operation} completed in ${duration}ms`);
if (duration > 1000) {
console.warn(`Slow query detected: ${operation} (${duration}ms)`);
}
return result;
} catch (error) {
const duration = Date.now() - start;
console.error(`${operation} failed after ${duration}ms:`, error);
throw error;
}
};
Performance Anti-Patterns¶
N+1 Query Problem¶
GraphQL
# Avoid: Separate queries per subject
query GetSubjects {
dataSubjects {
id
did
}
}
# Then separately query activities for each subject
# Better: Single query with relationships
query GetSubjectsWithActivities {
dataSubjects {
id
did
dataProcessingActivities(limit: 1, order_by: {triggeredAt: desc}) {
typeId
triggeredAt
}
}
}
Excessive Polling¶
JavaScript
// Avoid: Constant polling
setInterval(() => {
checkStatus();
}, 1000); // Every second
// Better: Use GraphQL subscriptions for real-time updates,
// or poll at reasonable intervals (30+ seconds)
Unbounded Result Sets¶
JavaScript
// Avoid: Fetching all records at once
const processAllSubjects = async () => {
const allSubjects = await getAllDataSubjects(); // Could be thousands
return processInMemory(allSubjects);
};
// Better: Process in batches with pagination
const processSubjectsInBatches = async () => {
let offset = 0;
const batchSize = 100;
let hasMore = true;
while (hasMore) {
const batch = await getDataSubjectsBatch(offset, batchSize);
await processBatch(batch.dataSubjects);
offset += batchSize;
hasMore = batch.dataSubjects.length === batchSize;
}
};
Production Configuration¶
JavaScript
const productionClient = new GraphQLClient('https://api.dxtra.ai/v1/graphql', {
timeout: 30000,
retries: 3,
retryDelay: (attempt) => Math.pow(2, attempt) * 1000,
credentials: 'omit',
mode: 'cors'
});
Next Steps¶
- Request Batching -- Execute multiple queries in one request
- Error Handling -- Robust error management
- Rate Limits -- Understand request limits
- GraphQL Reference -- Complete schema documentation