Code highlighting

Tuesday, July 14, 2020

Flights vs Feature management - practical overview


The primary purpose of flights and features both is to implement a controlled roll-out of new functionality into the product, so as not to disrupt existing business operations. One of Microsoft's primary goals with OneVersion is to ensure we do not break anyone.

By their nature, both the flights and the features are transient in nature, i.e., they will be removed from the product after some time, leaving the new functional behavior as default going forward.

Let's now break it down a bit more, looking closer at what a flight is, and what a feature is, and who has control over them, and when they are enabled/disabled.
  • A flight is a switch, which controls a certain, usually small, piece of business logic in the product, leading it one way or the other. Microsoft is in control of the state of the flight for customers in PROD. The decision to enable or disable a flight, as long as that does not impact the functionality of the environment, is not initiated by the company in most cases. Flights are, generally speaking, always OFF by default.
  • A toggle is a business logic / X++ construct, that is typically based on flights. Similar to flights, it is either On or Off. So what's interesting here is what the default out of the box state of the toggle is.
    • An "enabled by default" toggle, or, as it's more commonly known, a Kill Switch, is used for smaller changes, and the product behavior is changed right away, with no additional action from the users. Kill switches is a way for Microsoft to introduce bug fixes, yet safeguard against potential functional regressions, and as such, ensure we do not break anyone. If controlled by a flight, enabling the flight would turn the toggle and the new behavior off. Example: WHSShipmentConsolidationLoadLineLoadIdToggle
      • A kill switch will get removed after around a year from the moment of introduction, making the new behavior apply to everyone always from then on. 
    • A "disabled by default" toggle is used much less frequently
      • To enable certain troubleshooting logic that is performance intensive and thus undesirable in PROD. Example: WHSInventOnHandForLevelCalculatorMissingSiteIdLogToggle
      • To hide incomplete or work-in-progress features, so they cannot be enabled in PROD. Examle: WHSDockInventoryManagementFeature
      • Enabling the flight would mean enabling the toggle
  • A feature is, in a similar way, a toggle, which controls a usually larger piece of business logic, and is typically controlled by the superusers in the company. For this, they use the Feature management dashboard. Example: WHSWaveLabelPrintingFeature
    • Features go through a life cycle, where they are
      • In Development
        • Not available for use by end users in PROD
      • Private preview
        • Available for use by end users, including in PROD, but only based on prior agreement with Microsoft
        • Linked to a flight, which Microsoft needs to enable for the feature to appear
      • Public preview
        • Available for use by end users in PROD, based on decision to enable and configure the feature by superusers.
      • Generally available / Released
        • This is now the default behavior of the system, everyone has it. Depending on the feature, can still be configured "off".
    • There are corresponding kill switches in place to disable new feature behavior if a severe issue is discovered with the feature. Only reserved for very rare cases.
    • You can read more about Feature management here.

In an ideal world, partners/superusers should not need to know/worry about flights, and should control the behavior of the system solely through the Feature management dashboard. 

All of the above applies to PROD environments. The story with DEV/UAT environments is a bit different today for flights, where the partner/superuser has much more control. 

Note. Self-Service Deployment environments are controlled a bit differently, where above is also true for UAT type environments.

DEV / UAT environments

You can control the state of flights through the SysFlighting table. This is sometimes referred to as "static flighting". 
It's nicely described in an old post I found here, so I'll just paste the one line SQL statement you can use here instead:


It's really as simple as that, but remember to evaluate, if the toggle is enabled by default or disabled by default before you start adding flights there. Maybe the logic is already doing what you want.

Tip For Inventory, Warehouse and Transportation toggles it is very easy, as you can see it from the name of the class the toggle extends from:

  • WHSEnabledByDefaultToggle
  • WHSDisabledByDefaultToggle

FAQ / Typical scenarios

I enabled the flight in UAT/GOLD by inserting into SysFlighting, but when going live, the flight in PROD is not enabled. Microsoft, please insert the record for me.

Flights in PROD are controlled in a completely different way, not through the SysFlighting table, and are also not enabled on customer's request, but only when it makes sense after evaluation by Microsoft.

Important. You should not expect that just because you turned on a flight in UAT/DEV, and liked what you saw, you'll get the same in PROD. Microsoft can reject your request for enabling particular flighted (private preview) behavior in your PROD environment.

If you discovered what you believe to be a functional or performance regression, and you managed to link it to a particular kill switch, please log a support request with detailed repro steps, so Microsoft can evaluate and fix. We will then typically enable the corresponding flight to mitigate short term.

I'm trying to disable a flight but it's not working. I inserted a row in SysFlighting and marked it as Enabled=0, but system still behaves in the same way as before

Flights are, generally speaking, only Enabled. So it just really depends on what kind of toggle this is in X++. If this is a "kill switch", enabling the flight will revert the behavior to how it was before the changes. If this is a private preview feature, enabling the flight will enable the new behavior (or simply show the feature in the Feature management dashboard)

This is easy to understand if you look at the actual implementation in the WHSEnabledByDefaultToggle class.
public boolean isEnabled()
    if (flightName == carbonFlightName)
        return !isFlightEnabled(flightName);

This is basically reversing the condition for the flight. Meaning, enabling the flight will disable the toggle.

I enabled a feature, but I did not mean to, and now I cannot disable it

Some features are indeed designed in a way, where it is not allowed to disable them. The common reason here is that as part of enabling this feature, or as a result of using the feature for a short time, data was modified, which makes it difficult to revert to the old behavior. 

Also, not all features have a separate dedicated configuration switch in the product, so after you enable the feature, the product will in most cases start behaving in a different way.

So please carefully read the description of the feature, as well as evaluate the consequences of enabling it in UAT, before enabling it in PROD.

Microsoft enabled a private preview feature flight for me, but I still cannot see the feature in Feature management dashboard

Make sure you have clicked on "Check for updates" in the dashboard after 10-15 minutes after the flight was enabled.

Tip Microsoft also has a way of checking if the flight / feature is evaluated as On or Off for a specific environment, which can help you troubleshoot any issues, if it comes to that.

What is the difference between a Feature and regular Module parameters? For example, a Feature in HR - "Filter active positions" (This feature enables a position list filtered to only active positions). Why it is not an HR module parameter?

A feature is meant for controlling the roll-out of functionality, while a configuration parameter is meant for allowing the user flexibility in setting up their system. 

In the specific example above the intention with the "Filter active positions" feature is to expose it to all users (it's available in Feature management dashboard for everyone to see and enable), but in a manner which would not introduce new menu items / forms until this explicit decision is taken by the superuser, so as to ensure any documentation and internal task guides are properly updated beforehand. It is NOT the intention to make this behavior configurable going forward, and all companies will have access to the relevant menu item eventually (note, how the new FeatureClass property is set on it accordingly), while the feature class will be removed from the product. This approach also allows Microsoft to simplify the product, avoiding addition of unnecessary parameters.

That is not to say that both cannot co-exist. A module parameter or even whole new configuration screens can be added for proper setup of a new feature. They will only be exposed to the end users once the feature is enabled in Feature management. But then for the feature to function according to business expectations one or more settings need to be configured. An example of this is WHSShipConsolidationPolicyFeature feature, which you need to configure after enabling by setting up Shipment consolidation policies in the corresponding form.

More questions?

Please leave comments below, and I'll try to clarify!


  1. Hi Vanya,
    i would like to know how to find the name of the toggle which are not found in the macro. I want to find SplitPOByAccountingDateEnabledToggle feature to try to disable it on sysFlighting, but i can not find the name

    Daniel Antineus

  2. How to find the name where? You are listing the specific name yourself here.. SplitPOByAccountingDateEnabledToggle is a class in the product, which implements the IFeatureLifecycle interface, meaning it is a feature "flight", and I can see it is in Releaesd state.

    So you really need to think twice before trying to disable it, as the feature will eventually be removed in favor of the behavior being standard in the product.

    As this is a feature, you can turn the flight off by using SplitPOByAccountingDateEnabledToggle_KillSwitch as the name of the flight.

  3. Hi Ivan!
    This is a great post, thanks for that. But I have one question regarding activating flights in a dev environment. Other blog/forum posts seem to all also mention that you need to alter the web.config file under C:\AOSService\webroot, to get it to work. What's your take on that?

    1. Generally, I've not seen this for a long time as needed.

  4. Hi Ivan, Greetings!!, I have a simple query, The class
    SalesCopyingSetReturnAddressFromInventLocationFlight is called in another class in a "If" statement to perform a simple business logic. How to disable this flight to skip that business logic in Dev machines. And does the same code need to be moved to PROD? as you mentioned that Flights are handled differently in PROD env's

    1. Create a support ticket please, so they guide you in exactly what you need to do. I'm no longer with the AX team, so don't know if things have changed since

  5. We activated a flight in a DEV box and it gave us the desired results (no longer seeing an error we saw previously). We inserted the flight into a sandbox and the error is still occurring. I tried restarting services. Why will the flight not activate/register as being enabled in the sandbox, but it worked in the DEV box easily? Is there another step in a sandbox that we're missing?

    1. This post is a bit old by now, so I'd create a support ticket to see what the support team says - it might be that sandbox is already controlled through Microsoft..


Please don't forget to leave your contact details if you expect a reply from me. Thank you