Client Variables
Configure client variable storage, purge settings, and data persistence
Overview
Client variables are a ColdFusion feature for storing user-specific data across sessions without requiring cookies to contain the actual data. Unlike session variables that are stored in server memory and lost on server restart, client variables persist in a database, registry, or cookies, making them suitable for storing user preferences, settings, and other data that should survive server restarts and potentially span multiple visits.
The Client Variables page in CF Administrator allows configuration of storage locations, purge settings, and data source associations. Proper configuration is important for balancing performance, scalability, and data persistence requirements. While client variables were once popular, many modern applications now use session variables or database tables directly for better control and performance.
Storage Options
Cookie Storage
- Mechanism: Client variables stored directly in browser cookies
- Advantages: No server-side storage required, scales infinitely
- Disadvantages: Size limit (4KB), security concerns, network overhead
- Use Cases: Small amounts of non-sensitive data, stateless architectures
- Performance: Fastest option (no database access)
- Persistence: Until cookie expires
- Security: Data visible to users, easily modified - never store sensitive data
Database Storage (Recommended)
- Mechanism: Variables stored in database tables
- Tables: CDATA (client data) and CGLOBAL (global settings)
- Advantages: Unlimited size, survives restarts, centralized, clusterable
- Disadvantages: Database overhead, requires configuration
- Use Cases: Production applications, cluster environments
- Performance: Dependent on database performance
- Scalability: Excellent for clustered environments
- Setup: Requires datasource and table creation
Registry Storage (Windows Only - Deprecated)
- Mechanism: Variables stored in Windows Registry
- Platform: Windows servers only
- Status: Deprecated, not recommended for new applications
- Limitations: Single-server only, not clusterable, registry bloat
- Performance: Good for single server
- Migration: Migrate to database storage if currently using
Database Configuration
Creating Database Storage
- Step 1: Create datasource in CF Administrator
- Step 2: Navigate to Client Variables page
- Step 3: Click "Add" to create new client storage
- Step 4: Name the storage (e.g., "ClientStorage")
- Step 5: Select datasource from dropdown
- Step 6: Click "Create Client Database Tables" button
- Verification: Check database for CDATA and CGLOBAL tables
Database Tables
- CDATA Table: Stores actual client variable data
- Columns: cfid, app, data, lvisit (last visit time)
- CGLOBAL Table: Stores global metadata and purge information
- Indexes: Automatic indexes created on key columns
- Permissions: Datasource needs SELECT, INSERT, UPDATE, DELETE permissions
Multiple Storage Locations
- Purpose: Different applications can use different storage
- Default Storage: Set one storage as default for all applications
- Per-Application: Override default in Application.cfc
- Use Cases: Separate storage for different apps, testing vs production
Purge Settings
Automatic Purging
- Purpose: Remove old client variable data automatically
- Configuration: "Purge data older than X days"
- Default: 90 days (varies by version)
- Recommendation: 30-90 days depending on requirements
- Process: CF automatically removes records older than threshold
- Frequency: Purge runs periodically (hourly or daily)
Manual Purging
- Interface: "Purge Now" button in Administrator
- Use Case: Immediate cleanup before backup or maintenance
- Impact: May take minutes for large datasets
- During Operation: Runs in background, server remains operational
Purge Threshold Considerations
- Too Short: Users lose preferences if they return after threshold
- Too Long: Database grows unnecessarily, performance impact
- Inactive Users: Balance retention vs. database size
- Legal Requirements: Some industries have data retention regulations
- GDPR Consideration: Align with data retention policies
Monitoring Purge Operations
- Check CF logs for purge execution messages
- Monitor database table size over time
- Track number of records purged per operation
- Alert on failed purge operations
- Review purge threshold effectiveness quarterly
Storage Comparison
Cookie vs Database
Size Limit
- Cookie Storage
- ~4KB
- Database Storage
- Unlimited (practical limits apply)
Performance
- Cookie Storage
- Very Fast
- Database Storage
- Database-dependent
Scalability
- Cookie Storage
- Excellent
- Database Storage
- Excellent (with proper DB)
Clustering
- Cookie Storage
- Native
- Database Storage
- Requires shared database
Security
- Cookie Storage
- Low (user can view/modify)
- Database Storage
- High (server-side only)
Setup Complexity
- Cookie Storage
- Simple
- Database Storage
- Requires datasource and tables
Bandwidth
- Cookie Storage
- Sent with every request
- Database Storage
- Only cfid/cftoken sent
When to Use Cookie Storage
- Very small amounts of data (user preferences, UI settings)
- Non-sensitive information only
- Stateless architecture requirements
- No database available or desired
- High-scale applications where database would be bottleneck
When to Use Database Storage
- Moderate to large amounts of data
- Sensitive or important user data
- Cluster or multi-server environments
- Need for data persistence and reliability
- Reporting or analytics on user data
- Most production applications
Performance Considerations
Database Storage Performance
- Read Operations: One database query per request (if client variables used)
- Write Operations: Database write when client variables modified
- Connection Pool: Uses datasource connection pool
- Indexes: Ensure CDATA table properly indexed on cfid
- Optimization: Use fast database and optimize table
- Monitoring: Watch for client variable query performance
Cookie Storage Performance
- Zero Database Overhead: No database queries required
- Network Overhead: Cookies sent with every request/response
- Parsing: CF must deserialize cookie data each request
- Size Impact: Large cookies increase bandwidth usage
- Optimization: Minimize data stored in cookies
Performance Best Practices
- Use client variables sparingly - only for data that truly needs persistence
- Store minimal data - don't abuse as general-purpose storage
- Consider using session variables for temporary data instead
- Index database tables properly
- Use fast SSD-based database storage
- Monitor and optimize slow client variable queries
- Purge old data regularly to keep tables small
Security Considerations
Cookie Storage Security
- Visibility: Users can view cookie contents in browser
- Modification: Users can modify cookie values
- Never Store: Passwords, payment info, sensitive personal data
- Validation: Always validate and sanitize cookie-based client variables
- Encryption: CF can encrypt client variable cookies
- HTTPS Only: Use secure cookie flag in production
Database Storage Security
- Server-Side: Data not accessible to users
- Database Security: Protect database from SQL injection
- Access Control: Limit database permissions appropriately
- Encryption: Consider database-level encryption for sensitive data
- Backup Security: Secure database backups containing client data
CFID/CFTOKEN Security
- Session Identifiers: CFID and CFTOKEN identify users
- Cookie Theft: If stolen, attacker can impersonate user
- HTTPS: Always use HTTPS to protect cookies in transit
- HTTPOnly Flag: Prevent JavaScript access to session cookies
- Secure Flag: Ensure cookies only sent over HTTPS
- Expiration: Set reasonable cookie expiration times
Migration Between Storage Types
Cookie to Database Migration
- Create Database Storage: Set up datasource and tables
- Add Storage: Create new client storage in Administrator
- Set Default: Make database storage the default
- Gradual Migration: New users automatically use database
- Existing Users: Data in cookies until next write operation
- Cleanup: Old cookie data expires naturally
Database to Different Database
- Export Data: Use database tools to export CDATA and CGLOBAL tables
- Create New Storage: Configure new datasource and storage
- Import Data: Import into new database
- Update Configuration: Point applications to new storage
- Testing: Verify data accessible after migration
Migration Considerations
- Plan for temporary dual operation if needed
- Test migration process in development first
- Consider maintenance window for production migration
- Backup all data before migration
- Verify data integrity after migration
- Monitor for issues in first 24-48 hours
Best Practices
General Recommendations
- Use database storage for production applications
- Set reasonable purge thresholds (30-90 days)
- Monitor database table size and performance
- Use client variables only for appropriate data
- Consider session variables or direct database tables as alternatives
- Document client variable usage in application
- Test purge operations in development before production
Performance Best Practices
- Minimize data stored in client variables
- Don't store large objects or complex structures
- Index client variable database tables
- Purge old data regularly
- Monitor client variable query performance
- Use connection pooling for datasource
Security Best Practices
- Never store sensitive data in cookie-based client variables
- Use HTTPS in production
- Enable secure and HTTPOnly cookie flags
- Validate and sanitize client variable data
- Limit database permissions appropriately
- Consider encryption for sensitive data in database
Modern Alternatives
- Session Variables: For temporary data, faster than client variables
- Database Tables: For permanent data, more control than client variables
- NoSQL/Redis: For high-performance caching and session storage
- Local Storage: Browser-side storage for UI state (client-side only)
- JWT Tokens: Modern stateless authentication approach
Common Issues and Solutions
Client Variables Not Persisting
- Symptom: Client variables reset on each visit
- Causes: Cookies disabled, cfid/cftoken not being set, database connection issues
- Solution: Verify cookies enabled, check datasource connection
- Testing: Examine browser cookies for CFID and CFTOKEN
Database Table Creation Fails
- Symptom: Error when clicking "Create Client Database Tables"
- Causes: Insufficient database permissions, tables already exist
- Solution: Grant CREATE TABLE permission, check if tables exist
- Manual Creation: Can manually create tables using CF-provided SQL scripts
Large CDATA Table
- Symptom: Client variable database table grows very large
- Causes: Purge not running, purge threshold too long, many inactive users
- Solution: Reduce purge threshold, run manual purge, optimize table
- Prevention: Set aggressive purge settings, monitor table size
Slow Client Variable Performance
- Symptom: Application slow when client variables enabled
- Causes: Large CDATA table, missing indexes, slow database
- Solution: Purge old data, rebuild indexes, optimize database
- Alternative: Switch to cookie storage if appropriate
Cross-Domain Issues
- Symptom: Client variables don't work across subdomains
- Causes: Cookie domain restrictions
- Solution: Set cookie domain in Application.cfc (setDomainCookies)
- Configuration: Use .example.com to share across subdomains
Application.cfc Configuration
Basic Client Variable Setup
// Application.cfc
component {
this.name = "MyApplication";
this.clientManagement = true;
this.clientStorage = "MyClientStorage"; // Name from Administrator
this.setClientCookies = true;
}<!--- Application.cfc --->
<cfcomponent>
<cfset this.name = "MyApplication">
<cfset this.clientManagement = true>
<cfset this.clientStorage = "MyClientStorage"> <!--- Name from Administrator --->
<cfset this.setClientCookies = true>
</cfcomponent>Cookie Storage Setup
// Application.cfc
component {
this.name = "MyApplication";
this.clientManagement = true;
this.clientStorage = "cookie";
this.setClientCookies = true;
}<!--- Application.cfc --->
<cfcomponent>
<cfset this.name = "MyApplication">
<cfset this.clientManagement = true>
<cfset this.clientStorage = "cookie">
<cfset this.setClientCookies = true>
</cfcomponent>Using Client Variables
// Set client variable
client.userPreference = "darkMode";
// Read client variable
if (structKeyExists(client, "userPreference")) {
writeOutput(client.userPreference);
}
// Delete client variable
structDelete(client, "userPreference");<!--- Set client variable --->
<cfset client.userPreference = "darkMode">
<!--- Read client variable --->
<cfif structKeyExists(client, "userPreference")>
<cfoutput>#client.userPreference#</cfoutput>
</cfif>
<!--- Delete client variable --->
<cfset structDelete(client, "userPreference")>