Remanent Variables - RETAIN, PERSISTENT

Remanent variables can retain their value throughout the usual program run period. You can declare remanent variables as RETAIN variables or, even stricter, as persistent variables in the application. The requirement for full functionality is an appropriate memory range on the controller (NVRam, UPS). If there is no suitable memory range, the values of VAR RETAIN or VAR PERSISTENT variables will be lost in the event of a power failure!


  • CODESYS treats a VAR PERSISTENT declaration in the same way as a VAR PERSISTENT RETAIN or VAR RETAIN PERSISTENT declaration.
  • If you open a CoDeSys V2.3 project, the declarations of Retain variables are retained and remain effective. However, you must revise the declarations of persistent variables or create new ones. You must prepare a global variable list of its own for V3!
  • The AT declaration may not be used in combination with VAR RETAIN or VAR PERSISTENT!

RETAIN variables

You declare RETAIN variables by adding the keyword RETAIN behind the keyword for the type of variable (VAR, VAR_GLOBAL, etc.) in the declaration part of programming objects.

RETAIN variables retain their value after an uncontrolled termination (or online command Reset warm). On restarting the program the system continues to operate with the stored values. In this case CODESYS re-initializes ‘normal’ variables either with their explicitly specified initial values or with the standard initializations.

Variables declared as RETAIN are managed depending on the target system, but typically in their own memory range, which must be secured against power failure.

CODESYS re-initializes RETAIN variables in the case of

  • the command Reset origin
  • the command Reset cold (as opposed to persistent variables)
  • a repeated program download


In a POU:

 iRem1 : INT;

In a GVL:

 gvarRem1 : INT;

The degree of the value retention of RETAIN variables is automatically contained in that of PERSISTENT variables.

One possible application is a piece counter in a manufacturing plant that should continue to count after a power failure.


  • If you declare a local variable in a program as RETAIN, CODESYS stores precisely this variable in the Retain range (like a global Retain variable).
  • If you declare a local variable in a function block as RETAIN, CODESYS stores the complete instance of this function block in the Retain range (all data of the function block); however, only the declared RETAIN variable is treated as such.
  • If you declare a local variable in a function as RETAIN, this has no effect. CODESYS does not store the variable in the Retain range. If you declare a local variable in a function as PERSISTENT, this similarly has no effect.

Persistent variables

Unlike in CoDeSys V2.3, CODESYS treats persistent variables in V3 as follows:

You declare persistent variables by adding the keyword PERSISTENT behind the keyword for the type of variable (VAR, VAR_GLOBAL, etc.) in the declaration part of programming objects.

Like the RETAIN variables, PERSISTENT variables retain their values in the case of a Reset cold, a repeated download of the application and a Reset warm (therefore VAR PERSISTENT always corresponds to a VAR PERSISTENT RETAIN or VAR RETAIN PERSISTENT declaration). CODESYS thus re-initializes PERSISTENT variables only in case of Reset origin.

One example application for persistent variables is an operating hour meter, which should continue to count after a power failure and also after a repeated download of the application.

2 possibilities to define persistent variables

  • Declaration with the persistence editor in a special global variable list of the object type Persistent variables, which belongs to an application (VAR_GLOBAL PERSISTENT). There can only be ONE such list per application and CODESYS treats only the variables declared as PERSISTENT in this list as persistent. VAR PERSISTENT declarations that are present in other POUs are added to the list using the menu command Declarations ‣ Add all instance paths . Global PERSISTENT declarations in other modules are not permitted. As with Retain variables, there must be an appropriately secured memory range on the controller for persistent variable lists in order to guarantee the retention of values in the case of a power failure!
  • Definition in the Persistence Manager of the Application Composer. This takes place via a completely different mechanism to that for the declaration of the VAR PERSISTENT in the persistence editor and requires, for example, no special memory. Further information about this can be found in the chapters on the Persistence Manager of the Application Composer.


From CODESYS V3.3.0.1 a declaration with VAR_GLOBAL PERSISTENT has the same effect as a declaration with VAR_GLOBAL PERSISTENT RETAIN or VAR_GLOBAL RETAIN PERSISTENT.


Persistent variable list:

 iVarPers1 : DINT; (* 1. persistent+retain variable App1 *)
 bVarPers : BOOL;  (* 2. persistent+retain variable App1 *)
// instance path of the persistent variables created


  • you should avoid the use of the data type POINTER TO in persistent variable lists, since the address values can change in the case of repeated downloads of the application! CODESYS displays corresponding compiler warnings.
  • Each time the application is reloaded, CODESYS compares the persistent variable list on the controller with that of the project. In case of inconsistencies, i.e. changes of declarations and positions within the list, CODESYS requests you to re-initialize all persistent variables before the download. Inconsistency results from the renaming or deleting or some other change of existing persistent variable declarations.

Mechanism of persistence via VAR PERSISTENT

Changes in an existing persistent variable list can lead to re-initializations, i.e. to loss of persistence. If you anticipate frequent changes due to the area of application, such a list is not recommended in principle. This mainly concerns the change of name or data type of a variable that has already been declared (see below: ‘Changing an existing declaration’). The editor treats the insertion of new declarations or the deletion of existing declarations with newer CODESYS versions (> V3.5 SP1) as follows:

The editor for the persistent variable list arranges the persistent variables in the way the variables are expected on the controller. The technique is as follows: CODESYS stores a checksum and the length of the persistent variables on the controller. During a download, CODESYS uploads these values and compares them with the current values. All variables up to the specified length are compared with the current variables in the project. If the variables are still identical, then they remain uninitialized; the new variables are initialized. The editor intervenes in the variable list, i.e. it replaces deleted variables in the memory by placeholder variables and moves newly inserted variables to the end of the list. As a result you can apparently modify them as desired, but you create gaps. The consequence of these gaps is that the memory may no longer suffice for placeholder variables. Therefore, you should clean the gaps after a while (command Reorder list and clear gaps). After cleaning, however, the list will no longer match the list on the controller and the persistent variables will be initialized.

In order to retain the values beyond such a cleaning process, you must store the values in a recipe with the help of the recipe manager before the cleaning process and reload them afterwards.

Changing an existing declaration in the persistent variable list: if you change the name or data type of a variable, this is interpreted as a new declaration and causes a re-initialization of the variables at the next online change or download! It is a case of a change of a user-defined data type, for example: if a new variable is added in a structure, or if the type of a variable changes from INT to UINT in the depth of a used structure. Hence, complex user-defined data types are not suitable for the management in a persistent variable list, at least if it is anticipated that the definition of the user-defined data type will have to be continually changed.

Generally you should not have to continually change a persistent variable list. If you expect this to be necessary in practice, however, it is better to set up the persistence via the Persistence Manager of the Application Composer, since this offers better value retention mechanisms for such cases (disadvantage: considerable losses of performance in the case of large numbers of persistent variables). In special cases you can consider storing the current values of variables in a recipe from the outset in order to reload the variable values to the controller after the next download.

Overview table for the behavior with RETAIN and PERSISTENT declared variables

after online command VAR VAR RETAIN



Reset warm   x x
Cold reset     x
Reset origin      
Download     x
Online Change x x x

See also