Tag naming conventions

There’s always been conflict within my mind about what’s better when it comes to tag naming conventions, especially when it comes to SCADA platforms such as Ignition where tags can be grouped and structured: Do you use verbose names or abbreviations for your folders, and for devices (for the most part these will be UDT types, but not always), do you similarly use a verbose name or do you use its P&ID equipment ID?

I tend more towards the verbose names for both, but there are times where I have to convince myself…

Winery/Tank Farms/Fermenters/SWAP/Tanks/KF0031/Temperature/PV

Packaging/Barrel Washing/Stations/12/AV01


I’m after the rest of your thoughts on the matter and what you do?

When a customer asks my opinion (often not), I recommend common abbreviations that operators will recognize, so long as they aren’t so short as to be ambiguous across the entire client’s facilities, and facilitate templates/reusable windows & views. P&ID references and any other commentary go in the tag documentation property. I encourage the avoidance of spaces and any characters that wouldn’t be legal in a jython identifier.


I certainly see where you’re coming from, using abbreviations, however I find so much convenience in using more verbose names, as then these can simply be used in the display of their values as well. For example a setpoint could simply be named accordingly and then when displayed on the screen, its name can be used in the label. It’s also useful for trend names and alarm display paths (to an extent - if the tag path is too long, obviously this causes issues for reading efficiency). The same can be achieved with an abbreviated tag path, however it’s more of an issue for newcomers who haven’t yet learnt the terms defined. I’m still very much on the fence…
I usually grab the P&ID reference from my DeviceName UDT parameter (usually the tagname in the PLC) and map it through to an expression tag (in 8 I could simply read the parameter value instead).

Hi. I have exactly the same conflict.

I come from a chemical and process background where all PLC and SCADA tags would be the P&ID names. For example, a temperature transmitter tag could be:


A16: Area in the plant/PLC identifier
TT: Temperature transmitter
001: Device number (matching the P&ID)
Tags were stored in a folder structure depending on the location in the plant. The plants used a single PLC vendor and all tags were UDTs containing information including PV, setpoint, raw integer, high limit etc.

I have now moved into a manufacturing role. Our plant is made up of many discrete manufacturing cells and machines. We have PLCs from many different vendors and P&IDs are only used for a few machines. It is difficult to implement UDTs effectively as some machines will only output a “process” variable without any “metadata”. Here, the approach described above doesn’t work and (I think) the verbose approach is better. An example of my current convention is:


My new ignition SCADA system is currently in its infancy so I can easily make changes to the tag naming convention at this point. I would be very interested to read about the tag naming conventions used by others in manufacturing. Is there anyone willing to share details of their system?


1 Like

Keep in mind that the names of tags in your Ignition UDTs do not have to match the names of the tags in your PLCs. One of the greatest advantages of Ignition’s tag structure is that it can be organized intelligently in spite of lack of organization at the PLC level. Ignition UDTs should be organized to maximize the re-use of UI elements and simplify the construction of UI heirarchies.


This is an interesting discussion because while I try to standardize as much as possible, I work on varying range of projects that don’t always utilize PLCs! Sometimes there’s a P&ID, sometimes nothing. So, when there’s a P&ID, most if not all tag names match the drawings. However, for display, I leverage the tooltip and documentation tag properties. My display objects show the tag name if the documentation section is blank. I allow the end users to edit the documentation section (by means of popups) to enter in any name that makes sense to them for the instrument. BUT, I always link the tooltip back to the complete tag path (sometimes tricky with UDTs) so if there is ever a problem, the end user can tell me in layman terms what the problem is, and I can quickly identify which tag they are referring to.

1 Like

The first thing I did when developing my current project was to create a logical view of the entire IO scheme. I put all of these tags in a “IO Map” folder and then divide it up logically as it is in the field.

IO Map/PLC_X/Rack Name/Module Identifier/IO Address

The PLC name is usually a number based name, such as /PLC_9/

The rack name is usually location based or the name of the panel it is located in like OT_34 for operator terminal 34. If there are multiple racks, I add R1 or Rack2, /OT34_Rack1/.

The module scheme I designed to be shown in the same order of the slot positions and a simplified way to identify what is there: slotNumber_moduleType_channelCount like /4_DI_16/ to show 4th slot is a 16 channel digital input card. The slot number ensures the modules are listed in logical order in the tag browser.

Then the tag name is IO address prefixed by the IO type such as /DO_5:3 which is a digital output 5.3. I use a colon in the name because periods are not allowed in tag names

IO Map/PLC 9/OT 34 Rack2/5_DO_16/DO_5:3

The documentation property is where I describe the tag and so throughout the project the tag name and .Documentation are displayed next to each other.

This worked great for me as the automation technician, but its not a view that most people using the system fully understood and so I expanded upon it by creating UDTs that uses reference tags that reference the IO map. UDTs for Sensors, Hydraulic Control, Panel switches/pushbuttons and indication are used in stage views and panel views that divides the project into logical stages of the process. The tag path for these UDTs are also logically based in a stage view folder which looks like.

Stages/Zone ID(PLC # + description)/Stage Name/Sensor or Hydraulics/Sensor or Hydraulic name

The UDTs name is the referenced tag’s .Documentation

Stages/Zone 6 UT Station/UT Car/Sensors/West End Prox Sensor

Unfortunately you can’t bind the UDT’s name to the referenced tag’s .Documentation but using reference tags ensures I don’t have to configure the UDT much as they are just referencing tags that are already configured with scan rates and historical configurations.

Likewise for the panel view:
Panels/Zone ID/Panel Name/Controls or Indication/Switch or Pushbutton or Indication name

Ultimately I display these tags and UDTs with their name, status/value and a spark chart in template repeaters that show all relevant data per stage, panel, or IO module. The template repeater is configured to search the selected folder from a tag browse tree and so adding or taking away UDTs from a stage or panel is done in the tag browser, no view or window modifications are necessary.

For our projects, most of the time our customer doesn’t care what their tags look like.

Typically we group our tags by general production area/logical area.
Then each major piece of equipment gets a folder, and the each control device on that piece of equipment gets a tag.

So something like this:
Plant Area (Folder)
- Pump A (Folder) - Usually the tag name of the deivce
- MTR (UDT Tag)
- Amps (UDT Tag)
- FDS (UDT Tag)

This allows us to logically group alarms by folders. Most of the interaction is at the MTR tag level for popups etc… and that popup grabs all the alarms and displays them from the parent folder down. Our popups are built for displaying those so its easy to add associated alarms and tags to a device. Just drop it in the associated folder.

Could you elaborate on your last sentence here? I mostly use underscores but I do have spaces in my file path. I don’t think it’s caused any issues. In what situation would this be a problem? I was considering using more spaces in my naming conventions because the text appears in a more elegant way in a perspective button’s text property which I am binding to.

You should


the specific sentence from Phil so we don’t have to search for what you’re referring to


If I read this correctly, this might reference, for example, the input status of the P&ID equipment AA_TK01_LS01 (Area AA, Tank 01, Level Switch 01)?

If that’s the case, what about all of your other tags associated with that device?
For example for a digital switch:

  • on/off debounce timer setpoints
  • alarm timer setpoint
  • alarm reset command

I see this type of tag structure as being troublesome for use with templates, addition of functionality, and for general maintainability of the system. Also, what happens if the IO block suddenly needs upgrading, maybe they go from a DO_8 to a DO_16, or the IO block changes to a different rack? all of your tag references will need to change with it. In my opinion, you’re far better off abstracting your tags away from their inputs and associating them with something fixed and that has a connection with the process to which they belong (e.g. a P&ID equipment ID)


quote from pturmel: I encourage the avoidance of spaces and any characters that wouldn’t be legal in a jython identifier.

If you select the text from the author, a little QUOTE popup will show that you can use:


One of the techniques I find useful in heavily abstracted applications is to leverage jython’s special methods to redirect the reading/writing of arbitrary attributes to elements in file systems and hierarchies of all kinds. For this to yield readable code, the element names that become object attributes need to be valid jython identifiers. Or be munged into compatible form on the fly.

Hi Nick, thank you for your input. I wanted to try and improve upon the design and I knew it meant turning it all into UDTs. I also realized that I was combining 2 separate but related system components into 1 tag, those being the IO Device and the IO Channel. My tag structured represented the IO-Map and then used to identify the device by linking descriptions to each IO channel. I decided to split these 2 up into separate UDTs and link them together with the associated IO address like a relational database, the IO address being a key between the io device and io channel.

Input Module UDT

Digital Input Channel UDT - Definition

I created a 16 digital input module UDT to see what that would look like. It required creating another UDT, a digital_io_channel udt, and adding 16 instances to the input module UDT. The digital IO udt consists of 4 tags (only 2 are needed, I later added 2 more) and no parameters. The 2 needed tags are “IO_Address”(string) and “Value” (boolean). I define or partially define the values for these tags with parameters from the Input module UDT.

The 16-channel-input-module-UDT definition consist of 2 parameters, plc_name and io_base_address (and added later ‘wire_number’ and ‘drawing_number’), and 16 instances of the ‘digital_io_channel’ udt. The io channel udt definition is finalized at this level by sequentially adding a number to the end of the base io address to correspond to with each channel.

I created a new UDT definition for each module type, the new project I was working on had 3 generations of allen bradley PLCs. 1 PLC had over 150 IO modules and used 24 different modules types, and so I created 24 module UDT definitions and named them after the module’s model number.

Input Module UDT Definition

I can now create a new instance of any module by giving it a name and defining a few parameters.

Input Module UDT - Instance Example

##IO_Device UDT

I created a io_device udt as a generalized example of any io device to start building from. The idea from there is to create more specific udt types such as IO_Device/Level_Transmitter or /3-Way_Switch. The io_device UDT definition consist of tags that I would use to logically locate when searched for. It’s ‘Description’, ‘Device_Type’, the ‘Area_Name’, and ‘Equipment_Name’. This is an attempt to create a nicely organized view of the system but it immediately starts to grow in complexity. Organizing the system neatly is only partial achieved. The outliers, devices which have associations that span multiple areas and equipments demand more layers of complexity. Do I allow for more than 1 equipment and area association or do I create sub-areas or groups of equipment zones? Buttons and switches have these issues. 1 switch can control many machines but that is not the norm. A switch is often located in a different area than the equipment it is controlling. Do I now create another tag to associate a panel_id? Hydraulic systems also require consideration as they can span multiple areas and equipment.

In the IO_Device definition pictured, I create some tags that I will be removing as they are tags derived from the associated IO module and io_channel UDTs. I think I should keep that data separate and keep only the associative IO_Address tag as the shared key between them.

IO_Device UDT Definition

I used the plc tag name for the name of the io_device instance. The PLC tag naming convention used here is fairly typical, hard to understand for someone new to the system, but consistent and thankfully complimented with tag descriptions. The tag names were descriptive in same ways I wanted to organize them, meaning they usually contained the needed information and I could use the patterns to apply associations.

I created the 1200 or so io_device UDT instances from this 1 plc and placed them all in 1 folder. I envision something more organized within the tag browser, but at this stage it is not needed for the task of creating a screen to search for these io_devices. The search criteria will be more dynamic than a folder file structure, which is what is used for the IO_Map search tool.


In Vision I created a template for use in a template repeater to display these data points in logical groupings and added all relevant information so to be useful to anyone troubleshooting the system. The screens are intended to be quickly scanned through to find relevant information and collected if needed for short term monitoring by clicking on an instance turning it to a popup window

IO Map Search

The ‘Get Values’ button runs a script that browses the io device folder and pulls data needed for the selected module. The script runs fast enough, but I imagine there is a better way to do this and creating the io_device search tool caused me to rethink it all.

IO Device Search

At first I thought that in addition to the IO_Address tag, the IO_Device udt needed to have the IO_Address_Source_Path, the path to the associated io_channel udt instance, so that information could be more quickly derived for my search tool. I don’t want to run a script that performs the long operation of linking the io_channel’s path each time I do a search. From the perspective of the io_device, all the io_channel’s associated data is to be pulled, but whats the best way to go about that? I have a habit of using hidden tables on my screens that help me debug. In this case, I am generating a dataset to be used for a template repeater that is derived from a larger dataset on a pre-populated hidden table. The template repeaters displays the selected slices of information. I saw major performance improvements from having a hidden table referenced and realized that it could easily be populated by a dataset tag instead of by the script when the window opens. Each PLC could have its own dataset tag containing all the io_device info with its associated io_channel info and as long as its kept up to date, can be used for the purpose of this search engine.


Looking for some general knowledge about naming, I read through this feed and I didn’t see my concern.

Looking at length of tag names and folder structure. Can having long names put a heavy load on the system and potentially lead to issues. (I have seen in the past where a script somewhere doesn’t fire or doesn’t execute properly, then it does; and I was wondering if it was too much going on by design of actions triggering other actions, in multiple layers)

Specific Example:

Such as, I added an expression to an alarm pipeline binding and during testing I noticed it took a few seconds to enter the pipeline vs with no expression binding it was immediate.

The example:

Alarm tag path:
GasWellSites/Gaia/Wells/1M/GPU2000/Alarms/MVT-2X50 Pressure/Alarm_Status

This Alarm_Status tag has 4 alarms that reference other tags in the UDT with long names like “Alarm_HiHi_Enabled” and “Alarm_HiHi_Notify_Enabled” for the alarms enabled bit and the Notification Pipeline binding:

Expression Binding:
if({[.]Alarm_HiHi_Notify_Enabled} = 1, “Alarm_Notification”, “”)

This system is relatively small, I think about 20k tags but this comes to mind as the size continuously grows.

My main question is, if I changed things to shorter names/tagpaths would it make a substantial difference in the end.

Ex: Sites/Gaia/W/1M/G2000/MV2X5P/AS
AHHE = Alarm_HiHi_Enabled
AHHNE = Alarm_HiHi_Notify_Enabled
AN = Alarm_Notification (Pipeline)
if({[.]AHHNE} = 1, “AN”, “”)


To clarify, the lengthy names make it very easy to follow what is what, and anyone in the future can open the system and figure out what is going on and that is nice and all, but if it is going to slow the system down, that is not good.

Is it relevant to worry?

Not really. Longer strings will use a bit more memory, is all. Very slight performance impact. However, consider not using long names for elements that you expect to repeat in many places (with UDTs, most often) so that templates and indirect bindings in windows will be most flexible. For these, use shorter generic names. I also recommend never using spaces or special characters. If it isn’t valid in a jython variable name, I avoid it.

1 Like

Thanks for the fast reply, is there any documentation related to what to not use / best practices, or just stay away from spaces and special characters?

I only use alpha numeric, underscores, and dashes

1 Like