Visualforce Lifecycle
The Visualforce Lifecycle is the sequence of phases a Salesforce Visualforce page passes through on each HTTP request between the browser and the Salesforce server.
Definition
The Visualforce Lifecycle is the sequence of phases a Salesforce Visualforce page passes through on each HTTP request between the browser and the Salesforce server. The lifecycle begins when the browser sends a GET or POST to the page and ends when the server returns the rendered HTML. In between, the platform restores or initializes the page controller state, evaluates expressions in the markup, executes any controller methods triggered by user interaction, and saves the updated state for the next request.
Understanding the Visualforce Lifecycle is essential for debugging unexpected behavior on Visualforce pages: controller methods firing in the wrong order, view state size errors, action support not triggering, custom controller initialization happening twice. The lifecycle is documented in the Salesforce Developer Guide as a 7-phase sequence with specific entry and exit points where developer-written code runs. Knowing the phase order is the difference between guessing and reasoning about page behavior.
The seven phases of the Visualforce Lifecycle and how to reason about them
The seven phases of the Visualforce Lifecycle
Salesforce documentation describes the Visualforce Lifecycle as seven sequential phases. First, the browser submits a request (GET for initial page load, POST for action invocation). Second, the platform creates or restores the controller object (custom controller, standard controller, or controller extension). Third, the platform sets the controller properties from the view state (on POST) or from URL parameters (on GET). Fourth, the platform executes any action method (if the request is a POST triggered by a user action like a button click). Fifth, the platform evaluates all expressions in the page markup (the {!variable} bindings). Sixth, the platform serializes the controller state into the view state for the next request. Seventh, the platform returns the rendered HTML to the browser.
View state and the serialization step
The view state is the serialized snapshot of the page controller state that travels between the browser and the server on every request. The platform encodes the view state into a hidden HTML field and sends it back with each form post. On the next request, the platform deserializes the view state and rebuilds the controller object with the same field values it had when the previous request ended. This mechanism is what makes Visualforce stateful despite running on stateless HTTP. The view state has size limits (typically 170 KB total per request); pages with large data sets or complex controllers can hit the limit, producing a runtime error. Developers minimize view state by marking transient on large fields that do not need to round-trip, by reducing the size of collection variables, and by using read-only collections where possible.
GET versus POST and the entry point per phase
The lifecycle behaves differently on GET (initial page load) versus POST (action invocation). On GET, the platform creates a fresh controller, calls the constructor, runs any @action method specified in the page action attribute, evaluates expressions, and serializes the view state. On POST, the platform restores the controller from the view state, runs the specific action method tied to the user-triggered event (commandButton click, commandLink, actionSupport), evaluates expressions, and re-serializes view state. The action attribute on the page tag runs only on GET; if you put initialization logic in the constructor, it runs on every POST too, which is sometimes desired and sometimes not. Understanding which entry point fires on which request type is critical to writing controllers that behave predictably.
Controller methods, getters, setters, and expression evaluation
Expressions in Visualforce markup trigger getter calls on the controller. The platform evaluates expressions in document order, top to bottom, left to right. A getter that depends on another getter creates an evaluation chain; if the dependency is not yet computed, the dependent getter calls the depended-on one inline. This can produce surprising performance: a getter called inside a repeated section (apex:repeat or apex:dataTable) might fire many times. Standard practice is to cache expensive computations in instance variables and have getters return the cached value. Setters fire when the platform restores controller state from the view state at the start of a POST request, mapping the form fields back into controller properties. Setters fire before the action method, so the action method sees the user-provided values.
Common lifecycle bugs and how to debug them
Most Visualforce lifecycle bugs cluster around three patterns. First, double-invocation: the constructor runs twice on a single page load, because the page is rendered through a chained action. Fix by moving initialization logic to an explicit init method called from a getter or action. Second, view state size errors: the page tries to round-trip more data than fits in the 170 KB limit. Fix by marking large fields transient or by switching to AJAX-only data fetches. Third, action method not firing: the action attribute does not match the expected event, or the controller method has the wrong signature (a method called by an action must take no parameters and return a PageReference or void). Use the Visualforce Developer Tools debug log to trace the phases and identify which step is going wrong.
The lifecycle and modern alternatives
Visualforce predates Lightning Web Components by roughly a decade, and the lifecycle model reflects 2008-era server-rendered web framework conventions. Modern Lightning Web Components use a completely different lifecycle model based on standard web component primitives (connectedCallback, renderedCallback, disconnectedCallback) that run in the browser, not on the server. The Visualforce Lifecycle remains relevant for legacy code maintenance, for pages embedded in Lightning Experience through the apex:iframe pattern, and for certification exam prep. New custom UI in 2026 should use Lightning Web Components, not Visualforce. The Visualforce platform is supported indefinitely for backward compatibility but receives no new investment; understanding the lifecycle is increasingly a legacy skill rather than a current one.
Reasoning about and debugging the Visualforce Lifecycle
Writing or debugging Visualforce pages requires understanding the lifecycle. The four-step routine for working with the Visualforce Lifecycle covers: read the lifecycle phases in the developer guide, write controllers that respect the phase order, debug lifecycle issues with the Developer Console, and migrate legacy pages to Lightning Web Components when the time is right. Each step is a different relationship with the lifecycle; mature Visualforce developers use all four together as the situation requires.
- Read the lifecycle phases in the developer guide
Open the Salesforce Visualforce Developer Guide and read the Order of Execution section. The seven phases are documented with specific examples of what runs where. Reference this section every time you write a controller method, modify a getter, or add a new action handler. Without explicit knowledge of which phase fires when, controller code accumulates subtle bugs that manifest only under specific conditions (constructor running twice, setters firing in unexpected order, action methods triggering twice on rapid clicks). Bookmark the section; refer to it during every Visualforce code review.
- Write controllers that respect the phase order
Put initialization logic in an init method called from the action attribute on the page tag, not in the constructor (the constructor runs on every POST as well as the initial GET). Cache expensive computation in instance variables; have getters return the cached value rather than recompute. Mark large collection variables as transient if they do not need to round-trip in view state. Use immediate=true on commandButtons that should skip validation (the immediate=true case is one of the few ways to alter the lifecycle order). Document the phase-respecting patterns in the team developer guidelines.
- Debug lifecycle issues with the Developer Console
Open Developer Console and enable a debug log filter for the Visualforce user. Reproduce the bug. Inspect the log for the sequence of method calls; the debug log shows the controller constructor, every setter, every getter, every action method, and the view state size. Identify the deviation from expected lifecycle behavior. Common findings: a setter firing more than once because the page has two form fields bound to the same property; an action method not firing because the page actionRegion is misconfigured; view state exceeding 170 KB because a Wrapper class is holding too much data. Fix the issue and re-trace to confirm.
- Migrate legacy Visualforce pages to Lightning Web Components
For each Visualforce page in production, evaluate whether migration to LWC adds value. High-traffic pages benefit most because the modern framework is more performant. Complex business logic in a Visualforce controller usually translates to a Lightning Web Component plus a supporting Apex controller class; the LWC handles the UI lifecycle and the Apex handles the server-side work. Lower-priority Visualforce pages can stay as-is. Document the migration backlog in the project tech debt registry. Plan migration during major Lightning Experience modernization projects rather than as standalone work.
- The constructor runs on every POST, not just on initial page load. Initialization logic placed in the constructor runs more often than expected. Use the action attribute on the page tag for true one-time initialization.
- View state is size-limited to roughly 170 KB. Large data sets in controller fields exceed the limit and produce a runtime error; use Transient or AJAX-only fetches for large data.
- Expressions evaluate in document order, top to bottom. A getter inside an apex:repeat can fire hundreds of times; cache expensive computation in instance variables.
- Action methods require a specific signature: no parameters, return PageReference or void. A signature mismatch silently fails to invoke; the platform does not raise an error, the method just does not fire.
- Visualforce is in maintenance mode. New investment goes into Lightning Web Components; lifecycle expertise is increasingly a legacy skill for code maintenance rather than new development.
Trust & references
Straight from the source - Salesforce's reference material on Visualforce Lifecycle.
- Visualforce Order of ExecutionSalesforce Developer Docs
- Visualforce View StateSalesforce Developer Docs
- Visualforce Developer GuideSalesforce Developer Docs
Hands-on resources to go deeper on Visualforce Lifecycle.
About the Author
Dipojjal Chakrabarti is a B2C Solution Architect with 29 Salesforce certifications and over 13 years in the Salesforce ecosystem. He runs salesforcedictionary.com to help admins, developers, architects, and cert/interview candidates sharpen their fundamentals. More about Dipojjal.
Test your knowledge
Q1. What is the Visualforce Lifecycle?
Q2. What are the phases?
Q3. Why understand it?
Discussion
Loading discussion…