Choosing Ignition Client CPUs

Is it better to go for a high clockspeed, or high core-count for Ignition?
Is there a minimum benchmarking PassMark score that you would recommend for moderately large projects?

I’ve been burnt before going with a low-spec Intel Atom E3845 (993 PassMarks, 1.9GHz x 4 cores)

However without having different hardware to test with, I’m not sure what minimum I should be recommending, and if I should be choosing cores over clockspeed. From my understanding, for multi-threaded applications, more cores is better; whereas for older single-threaded applications, higher clockspeed is better.

Symptoms I was having with this processor were: slow navigation (even after windows had been cached), and slow performance in general for example with flashing objects on the screen not being in synch (despite having the combine repaint option set on templates/windows that had flashing objects)

Java Swing is single-threaded. So a decently high clock speed is helpful.

Aside from that, I recommend auditing your client and component event scripts to ensure no gateway round-trips are happening on the foreground thread. No scripted tag reads or writes, no scripted DB queries, unless they are delegated to a asynchronous thread.

1 Like

Thanks Phil, good to know RE Java Swing.
The only scripted tag reads/writes and DB queries are done on button actions, which I’m not overly concerned with. Generally their performance is good, but most importantly, they only occur when the user initiates the action.
I will have a look at some of my windows to make sure my background events don’t have anything suspect.

I have also had issues with remote clients across a VPN completely locking up as well when the client is first launched and the window is only just starting to load. The load just seems to freeze and the client no longer responds to mouse or keyboard. Killing the process is the only way forward. Any ideas?

Also, what about tag subscriptions and updates - are these all handled within the single Swing thread?
i.e. if a window has many tag subscriptions, will this affect performance due to single-threadedness?

I presume using lots of tag("") calls will affect performance, and these should be moved to indirect/direct tag bindings?

We have also been burned by low-end atom processors (don’t remember the exact speed and core count anymore).

When testing, tag access (be it though tag bindings or expressions) seemed to happen in the main thread.

But for us, the main speed improvement was to ban all UDT usage. I don’t know if that issue is fixed meanwhile, but if you display different parameters of an UDT, and you pass the UDT as reference, for every parameter you display, Ignition will load the entire UDT.

So if you have an UDT with 20 data points, and you display all of them in a popup, Ignition will load 20x20=400 tags on opening that popup. Transforming everything into tag expressions and indirect tags worked a whole lot better.

We always work on a local network (at least for production), so we have little problems with the round trip time to the gateway.

1 Like

Yeah I haven’t used UDTType parameters since I first started using Ignition and discovered their issues and limitations. I think the performance has been significantly improved in v8, but their limitations keep me clear.

The over VPN issues only occur when users try to access ignition from home to check on alarms etc.

This is common if you make the mistake of using runScript in a binding to execute alarm functions, use the isAlarmActive expression in a client binding, or do anything else that requires a request to the gateway on the UI thread (as @pturmel already mentioned).


Interesting, I didn’t think I was using runscript, but now that you mention it I based my alarm count template on one I found that uses it. I’ll fix it up! Thanks

No idea. Haven’t run into anything like this. Might be worth running such clients in a terminal so you can capture any last messages.

These are all done in the background, and can benefit from more cores. The gateway round trips to establish tag subscriptions won’t slow window loading, but a complex window will not fully populate until the background finishes. If you have such windows and want tag subscriptions to remain “fresh” even when the window is closed, add the relevant tags to a client tag change event script (that does nothing).

Yes, they cause more foreground CPU load than tag bindings, so I avoid tag() like the plague. But they don’t cause a gateway round-trip delay like a scripted tag read. The worst offenders are scripted tag or DB operations inside a runScript() or objectScript() expression binding.


If I can’t use runScript, how would I get the current count of alarms for a particular area?

Edit: I can use a memory tag with the runScript in its expression :wink: Slightly less easily configurable, but worth it if it increases performance

Consider a memory tag that is written from a timer event script. If the information is global, do it in the gateway. If context specific, do it in the client, with a client memory tag.

Thanks Phil. What’s the benefit in using a timer script instead of runScript within the tag’s expression?

We have an UDT instance per “Zone” to count all active alarms for that zone. The UDT parameters just encode the displaypath.
Inside the UDT, there are 4 expression tags using runscript calls (for the low, medium, high and critical alarms). As these happen on the gateway, they are fast.

On the client, we just point to the right UDT instance based on what page is open. That way the client doesn’t have to poll for changed alarms.


I wish this was attached to each folder. It’s done like this in another SCADA I’ve used, where each folder has a bunch of properties attached to it, some of which are counts of alarms, highest priority, etc.
Great idea though using a UDT with all you might need :slight_smile:

Timer events gracefully degrade on a busy gateway without impacting the scan class/tag group, and aren’t forced to run at that class/group rate. And have access to the project’s script modules.

1 Like

I just tested one particular window that crashed every time it was launched remotely, after removing all alarm query runScripts (I found more that were part of navigation buttons as well as an alarm symbol template that I use for showing device or area alarms), and the window loaded perfectly with no crashes :scream:.
I feel the alarm query functions should have disclaimers on them! Although I probably should have guessed the performance would suffer by using them…

Thanks for the tip!

1 Like

FWIW, I think there’s a few considerations not brought up here:

  • Licensing cost: While Ignition doesn’t charge a per-core price, most commercial OS and databases do. Nothing worse than buying a 112-core server and then seeing the licensing fees.
  • Dual use: If Ignition and the database are on the same server, then the database will gladly eat up all the cores you throw at it (and memory, and disk speed, etc), especially if you use complex SQL to do more work in the database and less in Ignition. Whether or not you’re limited by database CPU performance is difficult to even guess without going live, unfortunately.
  • And finally, how you built your project. Some GUI components are notorious for bogging down both the frontend and backend in single-threaded ways. Plus Jython is inherently almost as single-threaded as Cython is, despite the lack of GIL. To effectively use many-cored beasts, you either have to have a project with very light backend work, or tons of clients, both OPC and GUI, or learn to write explicitly threaded Python for every task that might take some time. threading.Timer() will become your friend, and you’ll have to take an async view of completion and minimize interaction with the GUI (but your UIs might become more responsive!).

I haven’t built enough Ignition 8 projects to know how it, and Perspective, respond differently, other than UDTs and some other features being massively more performant in 8, but the same broad guidelines should still hold up.

Uhm, how is this an issue for client machines? The OP isn’t asking about the machine the gateway runs on.

Same here.

Please support this assertion. I am quite familiar with the java source code for Jython and don’t find this to be true at all. Unless you mean the single-threaded nature of Java Swing… ? Or crappy parts of the python standard library (not an issue when using java classes in jython)?

Oh, I misread the question, I actually thought it was about the server side.

And yes, mostly the Jython standard library. The core of it is completely distributed to be properly multi-instanced (or it wouldn’t be usable for component work at all), but it’s so easy to block in unexpected ways.

My standard advice on this forum when considering some functionality from the python standard library is to ask “is there a standard java class or package that can do this?” And if the answer is yes, use the java classes instead.