CFML Scopes and the Request Lifecycle
Understand where data lives, how long it survives, and why variable scoping is one of the most important skills in legacy ColdFusion maintenance.
Why Scopes Matter
ColdFusion has many places where a variable may live. Unscoped variable lookup made short code possible, but it also created ambiguity, accidental data exposure, and difficult bugs. A maintainer should identify both the variable name and its intended lifetime.
| Scope | Lifetime | Typical Use |
|---|---|---|
variables | Current template or CFC instance | Page variables and private component state |
url | Current request | Query-string input |
form | Current request | Submitted form fields |
cgi | Current request | Server and request metadata |
cookie | Browser-controlled persistence | Small client-side identifiers or preferences |
request | Current request, across includes/custom tags | Request context shared by templates |
session | One visitor session | Authenticated identity and per-user state |
application | Shared application lifetime | Read-mostly configuration and cached data |
server | Entire ColdFusion server | Server-wide data; generally avoid for application state |
attributes | Custom tag invocation | Inputs passed to a custom tag |
caller | Calling template from a custom tag | Returning values to a custom-tag caller |
arguments | Function call | Function and CFC method parameters |
Always Scope Request Input
<cfparam name="url.customerId" default="0"> <cfparam name="form.status" default=""> <cfset variables.customerId = Val(url.customerId)> <cfset variables.status = Trim(form.status)>
Do not rely on ColdFusion to decide whether customerId came from URL, FORM, COOKIE, or another scope.
Function-Local Variables Before CF9
The explicit local scope arrived after the MX era. In MX CFC methods, declare temporary variables with var. For maximum compatibility, place those declarations before executable statements.
<cffunction name="findCustomer" access="public" returntype="query" output="false">
<cfargument name="customerId" type="numeric" required="true">
<cfset var customerQuery = "">
<cfquery name="customerQuery" datasource="#variables.dsn#">
SELECT id, name, status
FROM customers
WHERE id = <cfqueryparam value="#arguments.customerId#" cfsqltype="cf_sql_integer">
</cfquery>
<cfreturn customerQuery>
</cffunction>
var-scope a temporary method variable can place it in the CFC's shared variables scope. Under concurrent requests, one call can overwrite another call's data.Shared Scope Locking
Session, application, and server scopes can be shared across requests. MX-era applications often use cflock when reading or writing them.
<cflock scope="session" type="exclusive" timeout="5">
<cfset session.lastCustomerId = variables.customerId>
</cflock>
<cflock scope="application" type="readonly" timeout="5">
<cfset variables.supportEmail = application.supportEmail>
</cflock>
Do not hold a lock while performing a slow query, remote request, file operation, or mail send. Copy the needed value inside the lock, then do the slow work after releasing it.
Request Flow
- The web server maps a
.cfmrequest to ColdFusion. - ColdFusion locates the applicable
Application.cfmor, in MX 7,Application.cfc. - Application and request lifecycle code executes.
- The requested template and its includes/custom tags execute.
- Generated output is returned through the web server to the browser.
Scope Inspection During Debugging
<cfdump var="#url#" label="URL Scope"> <cfdump var="#form#" label="FORM Scope"> <cfdump var="#session#" label="SESSION Scope">