Sunday 7 October 2012

Velis Auto Brightness manual

First steps

When you first start the application, you will be greeted with a simple wizard allowing you to select the basic settings that will tailor the app to your preference. Any settings you define in this wizard can be changed later so don't worry about making a wrong selection. For more info on that, please see the wizard documentation in the settings section.

The main app form is displayed here and is designed to give you easy access to the common functions you may need. On the left side you have the selection of available screens: main, settings, manual graph edit, manual, store, change log and about. If you have a large screen, the selection may be expanded to show you text as well. Beside the selection you're looking at the main app form.
There's a quick display of current sensor readings, a brightness graph, a couple of quick switches and the preset buttons.

To enable Velis Auto Brightness, check the "Automatic brightness" switch or checkbox - depends on your Android version, but functionality is the same in both cases. Also make sure you disable any previous auto brightness apps you may have installed. Enabling automatic brightness will do two things: it will disable system auto brightness routine and start tracking your light sensor while adjusting brightness according to the default brightness curve you see in the graph.

Your next step then is to load presets and see which one may suit your needs best. You will find the presets in the settings screen, which is accessible by pressing the gears icon in the screen selection list. You will find presets towards the end of settings menu.

Menu / screen selector

This is the list you see on left side of the screen. It displays possible screens you can display to work with the application. Additionally, by swiping left or right you can expand or contract the list itself if you need more verbosity or would like to tuck it away.
A right swype will expand the list to full size.
One left swype will shrink it to icons display.
Another left swype will hide the list.

Manual graph adjustment / fine tuning

If no preset suits you, you will notice that the graph has two red lines marking current brightness state. Each of these has a slightly bolded handle at its end. You can touch and move these handles to adjust the brightness curve any way you like. When you do so, you will also notice two buttons appearing below the graph. You can either apply or cancel your changes with these buttons. Also, if you accidentally touch a handle and start the adjustment, the app will automatically cancel your change after an adjustable period of time.


Initially there won't be any presets stored in your device. Using the preset buttons gives you the option of saving your custom-made brightness graphs under your own names - just make sure to keep them short :-)
Long-pressing any preset button will present a popup menu allowing you to save or delete a preset.
Short-pressing a saved preset button will load the brightness curve for that preset.

Settings explanations

Run settings wizard

The settings wizard will first reset all your settings to default. Then you will follow six simple screens to set the most important aspects of app operation.
The wizard offers choice for the foolowing settings:
  • Brightness preset: select a rough brightness according to your preference. The selected preset will represent a starting point for your personalised brightness curve and is a very important selection: you want your screen to be appropriately lit so that you can see what is displayed on it, but not lit too much because that would consume too much battery.
  • Sensor sensitivity (afects multiple settings): with this setting you tell the app how responsive it should be to environment light changes. You must carefully balance fast response which may introduce some flicker and slow response that tries provide you with a stably lit screen as much as possible.
  • Charging brightness: allows your screen to be brighter when the device is charging
  • App activation: the last wizard setting alows you to enable the app. The app needs to be enabled to do its magic.
  • The last wizard screen makes a brief introduction to the graph on main app screen.

Application language

Allows you to select any of the app-supported languages even if your phone's settings are to a different language. Helpful if you want this app in a language that otherwise isn't well supported on your phone.

Excluded apps

Use this setting to select apps that will disable Velis Auto Brightness when on top. Android APK installer is one of such apps which fails to work properly if there's a screen filter active on your phone. Disabling auto brightness when such apps are running ensures their proper operation.
Please note that retrieving installed apps list is a fairly time consuming process. The list will update in the background even as it is displayed on screen. You can however work with it even as such updates are performed.

Service activation section

In this section you will find the settings that manage Velis auto brightness operation (whether the app works or not).

Automatic brightness

This setting enables or disables the app's automatic brightness handling. Setting it to on will naturally enable the app. This setting is also set by the "automatic brightness" switch in apps main window.

Disable system handler

This setting disables the Android OS system auto brightness handler. Setting it to on will disable the OS handler. When using Velis auto brightness it is recommended this setting to be on, otherwise system will interfere with Velis app operation.

Optional update system brightness setting

Turning this setting on will update system brightness setting in the settings app. This normally has no functional benefits, but you may enjoy yourself watching the brightness slider move as the light changes :-) This option may have a minor additional impact on battery usage when enabled.
However, this setting may actually become necessary if you're on android 4.3+ and you don't want notification. Since Android OS may kill the app at times, turning this setting on at least makes sure that screen brightness doesn't change during the time it takes for the app to restart itself.

Interactive notification

Interactive notification has several functions that allow you to quickly work with Velis Auto Brightness settings.
  • There's a button for turning service on and off
  • Pressing on the progress bar will set brightness appropriate to the spot where you pressed
  • The Confirm and Cancel buttons will Confirm or Cancel any manual brightness setting into the current brightness graph. They are only visible once an adjustment in brightness had been made.
  • Pressing anywhere else on the notification (the icon) will open main app screen
If you leave the manual brightness setting unconfirmed it will remain in effect until you first turn off the screen.
This functionality does not work on android 2.x since it doesn't support custom areas for press detection. Without this functionality the notification wouldn't be very interactive :) Users of Android 2.x only have the hidden notification which is necessary for the service to stay alive at all times.
Only users of android versions 3.0 and higher will see this option in settings and will be able to choose between hidden notification or interactive one.
Since version 3.55.151 users of android 4.3 and higher can opt out of notification with a workaround that will hopefully keep the service running even though Android would have killed it. See FAQ about how to activate this.

Sensors section

This section contains a list of all supported sensors and allows you to choose which sensors will be used for app operation.

Brightness sensor

This setting tells the app whether to use the brightness sensor or not. This sensor is pretty much essential for app operation so at the moment it is not sensible to turn it off - you would lose the auto brightness operation altogether since this sensor is the only source of brightness information for the app right now.
Later, maybe, when cameras are also supported, the app will have enough info from cameras and this sensor will be safe to turn off.

Screen touch

This setting detects when you are touching the screen and disables screen brightness updating during such times. This results in screen keeping its brightness constant while you are using the device thus minimising the distractions that would otherwise result from changing screen brightness.
Typically you would set this to a large value, say, 30 seconds and this setting will make sure your screen stays rock solid while you are reading a web page or e-mail.
Triple tapping the screen inside 2 seconds will immediately update screen brightness to current sensor reading.

Proximity sensor

This sensor detects whether there is something over your device (e.g. your hand). When this is detected, the app will not adjust brightness according to brightness sensor since the readings are invalid due to additional shade created by your hand.
Since proximity sensors have quite limited range, the app cancels brightness adjustments from 3 seconds before the proximity sensor triggers to 3 seconds after proximity sensor releases.

Front / back camera

Enables the respective camera, if available on your device. Cameras should only be used if your light sensor is not functioning properly. They are a lot less precise and consume a lot more battery.
If brightness sensor is active, results from camera readings will be ignored, otherwise results from the camera reporting higher environment brightness will be used.

Camera read interval

Consider this interval well because cameras require a lot of power to operate. Additionally, taking a picture from camera is time consuming, so the shortest interval - 1 second -  might not even be achievable on your device.
In any case using cameras will not be very responsive in comparison to a dedicated light sensor.

Screen-on sensor override

When you frequently move among bright and dim environments, your device will always try to adapt to light conditions in the current environment. This is all fine and dandy if you change the environment with screen turned on so that light changes are tracked in real time. When you turn screen off however, your device will stop tracking sensor changes to conserve battery.
So when you turn screen on, the previous brightness value will still be in effect. If you came from a bright environment, your screen will be bright until it adapts to the new light conditions. If you came from a dark environment, the situation will be reversed.
You can counter this with two settings: this one and Smoothing override, which is explained a bit later in this manual.
Screen on override tries to counter the undesired brightness settings by forcing display brightness to match the entered lux reading when you turn display on. So if you like to go from dark to lighter display, you would enter a dark lux reading here, below 100. If on the other hand you like your screen to be bright initially, you would enter an outdors reading, something above 1000. Or you can go down the middle with a setting between 100 and 1000 and expect your display brightness to only correct a bit when you turn the screen on.

Additional brightness

Settings in this section allow setting two modes for additional brightness:
  • Additional brightness when charging
  • Permanent additional brightness
Both behave the same, but the former is limited to condition when your device is plugged into a charger and the latter is always applied (whether charging or not).

Additional brightness

Set how the additional brightness is applied:
  1. no extra brightness: what is says on the tin - there will be no brightness change when charging
  2. add percent of calculated brightness: if app calculates the brightness to be set to a certain percent (x), the calculated x will be increased by the set percentage (x = x + x * percentage)
  3. add percent of full brightness: this will add a constant percent of total brightness (x = x + percentage total)
  4. combined: calculated and full brightness: this method just adds method 2 and 3 to achieve a combined effect

Additional percent to add

This is the percentage to use in the above methods. Setting this to 10% will result in the following calculations for the above methods:
  1. x = x
  2. x = x + x * 0.1
  3. x = x + 100 * 0.1
  4. x = x + 100 * 0.1 + x * 0.1
The value can be negative. A -50 value will result in 50% reduction of calculated values according to the above formulas.

Sensitivity section

The sensitivity section regulates app's sensitivity to sensor readings changes. The higher the sensitivity, the more responsive the app, but that may also lead to some unwanted brightness changes. Find the perfect balance between responsiveness and number of changes for your taste.
This section is also for handling flickering issues. If you are experiencing flickering, try increasing change sensitivity and smoothing time.

Brightness change sensitivity

The higher the percent, the less sensitive service will be. At 100%, the app wouldn't react even if you put your device under the sun, at 10% a pretty significant sample change will need to be read from sensors and at 0% the service will react to the tiniest change in sensor readings.

Smoothing time

When changes are big, the sudden transition may be unpleasant. This setting handles such situations and smooths the transition over the specified time. Note that the time is in milliseconds (1/1000th of a second).
Technical explanation: The app will try to smooth the transition in at least 5 steps, but these steps will not take less than 75 ms and no more than 150 ms. A setting of 400 ms will thus make 5 updates in 80ms each while a 2000ms setting would do 13 updates in 150 ms intervals.

Smoothing time downwards

If you want your device to be responsive when brightening up and a bit slower when dimming (or the other way around), you will specify a different smooting time in this setting. This will be helpful when you are driving under street lights, for example. Specifying a relatively long smooting down time will keep the brightness levels appropriate to the lights being driven by.

Smoothing override

This setting helps your device adapt faster to sudden light changes such as light turning on in the room or an unexpeded ray of sun in your shade. The setting uses the same scale as the brightness change sensitivity setting, which is the logarithmic lux scale divided into percent sections. Each percent represents one length percent on the graph horizontal axis. The setting translates its percentages directly to graph axis.
Smoothing override setting analyzes each light sample to see if it exceeds override threshold. If it does, the new light reading will take effect immediately, as if there was no smoothing in effect.

Superdim threshold

Superdimming turns on an additional screen filter which dims the screen beyond what your display backlight would be capable of.
The filter works in a linear fashion dimming the screen proportionaly from the threshold down to zero brightness as specified by the brightness curve. Actually it behaves exactly as the backlight control works (without the filter) only that it does not control the backlight, but dims the screen through a semi-transparent overlay. It is more accurate than the backlight and has the prefect minimum and maximum (the backlight may not respond in perfect grades down to zero brightness).
The end result is that enabling filter at threshold 100% (always active) simply introduces double filtering of screen brightness (once for backlight and once for filter) which produces a quadratic brightness function. Normally though you would enable the superdimming for the lower 15% - 25% of brightness to help achieve the desired low screen brightness.

Warning: This is a pretty strong function which could result in your screen being to dark to work with so the app has a built-in safeguard which prevents you from changing the threshold when such a change would produce screen brightness below 7%. If such a condition is detected, the superdimming functionality will not be activated.

Please note that standard LCD screens with backlight will not save additional battery. Take care to enable superdimming only at brightness level below which the brightness otherwise remains constant. Enabling superdimming at a higher brightness would produce unoptimal results because backlight would produce light only to be cancelled out by the filter.
On AMOLED displays the filter always produces battery savings.

Graph settings section

You will find settings for brightness curves and editing timeout here.

Brightness preset

Presents some presets you can choose from to start you up with customising your auto brightness. Each preset provides a different brightness graph so be sure to test it out a little to see how it suits you.

Graph abort timeout

Number of seconds of inactivity before app automatically cancels your manual update to graph.

Launcher widget parameters

The launcher widget parameters allow you to change operation of the widget. This section only appears if you have Tasker / Launcher premium content purchased. Otherwise the settings are set to default values which you cannot change.

Widget graph samples

This setting declares graph horizontal resolution. The higher the number, the smoother the graph will be, but that will also take some device memory. Normally the default setting should be OK for most screens, but if you have an exceptionally high or low resolution screen, you can adjust this parameter so that the graph looks better on your screen.
Allowed values are between 10 and 2000 samples with a default of 400.

Widget graph time period

What's the period (in seconds) to display in the graph? The default is 86400 (one day), but if you're a fast-paced individual, you can decrease this time to monitor light changes in a shorter interval down to the last few seconds. Be aware though that decreasing this parameter too much can have an impact on battery usage because drawing graphs is quite a CPU intensive task.

Widget graph stats percentage

Clicking the graph section of the widget will bring up a dialog with brightness statistics for the selected time period. Those statistics will be grouped by this percentage. Entering 20 (default) will create 5 groups, a 10 would create 10 groups and a 50 would only create 2 groups.

Transparent widget

The widget will be rendered transparent or opaque on the launcher background.


Will open app changelog page.

Auto brightness blog

Will bring you to app homepage.

Manual graph editing

Dragging handles only supports smooth brightness curves with no sudden changes. If you want more advanced curves that use steeper angles, you will need to edit graph data through manual graph edit screen.
The graph data is arranged into lines, each line representing one point on the graph. Each line starts with a fixed string "Pt:", followed by a single space, followed by integer sensor reading, another space and finally the brightness to apply at that sensor reading. Any other format than this will be rejected when you push that "OK" button.
Sensible sensor readings range from 0 to 15000. A point with a zero reading must be present at start of the list. A point with >= 15000 reading must be present at end of the list.
Allowed brightness values range from 1 to 255, 1 being darkest and 255 being the brightest screen.

If you want a steep "step" in your curve you will have to define two points with very close sensor readings and much different brightness settings (e.g. Pt: 100 20    Pt: 101 100).

In-app store

The in-app store is where you can purchase premium content or just support the developer because you think this app is nice.
There are three items of note on this dialog:

Selection of item for purchase

At this time two items are available: Tasker support and Developer support. Buying Tasker support enables Tasker / Locale conditions and settings to allow for controlling this app from Tasker or Locale or any other compatible manager. In addition to this, the Launcher widget functionality will also be enabled when it is available.
Buying developer support allows you to express your enthusiasm over this app to me. It helps fund various expenses I have with development of this app. It doesn't however bring YOU any immediate benefits.

Below these selections there's a short description of what purchasing each item does.

The Buy button

Pressing the buy button will enter the Android Play store where you will be able to securely purchase the selected item. The procedure is similar to any other purchase you make in the Play Store.
Note that after purchasing one-time items such as Tasker support, the item will become grayed out - you cannot purchase it again since you already own it.

Purchased items list

Shows items you already purchased. Note that Developer support will not show here since it's not an "owned" item.

Tasker plugin / Locale plugin functionality

Velis auto brightness will also function as a plugin for these two popular tools. With the exception of profile selection, this is considered premium functionality which you need to purchase from the in-app store.

Conditions supported

Current light reading 

Will report current light reading to Tasker / Locale. Note that this is a very frequent event so you may notice increased battery usage when this condition is active. Using this event enables you to react to environment changes as detected and calculated by the app. The sensor value reported will be the same as in the app itself, using all available and active sensors.

Current proximity reading

Will report current proximity sensor to Tasker / Locale. Using this event enables you to react to changes in this sensor readings such as turning screen off when sensor triggers.

Calculated screen brightness

This is similar to current light reading, but reports the brightness as calculated from detected lux and current brightness graph. This is also a very frequent event which may cause additional battery usage when active.

Screen on

This condition reports screen on and off events. This condition is included despite it being in the Locale condition plugins sample - since the app uses this information anyway and this condition is not provided to Locale by default... Will allow you to monitor screen on / off states.

Settings supported

The settings supported behave exactly the same as in the app itself so here's just a list of supported settings. If you need to understand how they work, please read the Settings section above.
  • Automatic brightness
  • Brightness sensor
  • Proximity sensor
  • Change sensitivity
  • Smoothing time
  • Select profile (free)


For some reason the screen goes very bright when manually installing / uninstalling an APK

This is caused by VAB disabling itself because by default Android APK installer is in the excluded apps list. This is necessary because APK installer refuses to work if there's an overlay window active.
In order to not experience this issue (if you're not using the Super dimming feature) is to remove the APK installer from excluded apps list (available in the settings screen) - but then you won't be able to manually install apps or give apps permissions.

I have (insert your phone model) and the brightness changes are extremely noticeable / skipping / not smooth / flickering a lot

Some devices can only adjust display brightness in rather large steps. Examples include flagships like SGS 3, Nexus 4 and Galaxy note 2, but other phones / tablets are also reported to be affected.
There is a solution for this issue, but it only makes sense on the AMOLED displays (most of the phones with such issues have those displays):
As of v3.05.122 the app supports only managing screen brightness through its super dimming feature. If you set super dimming to 100%, it will become the only method of adjusting screen brightness and will not try to adjust brightness through backlight (which is non-existent on AMOLED displays).
However, there's a caveat: super dimming has a completely linear brightness function very unlike the backlight method. As a result, screen will be much darker in the lower brightness sections. Using a brighter preset such as "AMOLED bright" is recommended.

My phone alternates light readings in rapid succession (hunting) making the screen change brightness all the time. How can I fix this?

Some phones have pretty bad light sensors. Even flagships such as SGS3 can be affected. To solve this problem, enable "Erratic sensor readings fix" or / and set the "smoothing time downwards" setting to a large value, like 10000 or 15000 milliseconds (10 or 15 secs). Te latter will not solve the problem as such, but will almost entirely eliminate the symptoms.

Why is my camera not detected?

Camera detection sometimes fails for various reasons. Currently the solution for that is to open developer options dialog (see below on how to do that), turn off camera support, close the dialog, open it again, enable camera support and close it again. Cameras should be detected now. If not, try again, until successful.

Since Android 4.3 I there's this notification. What is it?

The Android developers decided to solve the problem of lackluster API by exposing hacks people have to do in order to achieve certain functionality. In this case, the auto brightness service needs to run uninterrupted in order to provide proper support for the user. Without the service there is no auto brightness. The only way to make Android not kill the service at its leisure is declaring a notification.
Hence the notification in the notification area.

Since version 3.15.141, there is an interactive notification option which is quite powerful.
Since version 3.55.151 there is an option to fully eliminate the notification. This latter is still in testing though. It can only be activated through developer options dialog by setting the service keep-alive interval. It is recommended that you not use superdimming and that you turn on optional system brightness updating in settings. If you can meet these conditions, the keep-alive interval can be relatively long, say 5000ms (to make sure auto-brightness is updated at least every 5 seconds). If these conditions cannot be met, the interval must be short, such as 500 ms in order to re-run the service as soon as possible after it being closed..

What's this developer options dialog that is mentioned all over the place?

There are some settings that aren't yet ready for general public and some settings that never will be (because they are only meant for helping me debug, etc.)
All these settings are gathered in the developer options dialog which is accessible through long-pressing the proximity sensor reading on app main form (circled red in the picture).

Privacy policy

This privacy policy discloses the privacy practices for Velis Auto Brightness Android app (VAB).

Information Collection, Use, and Sharing

The app does NOT collect nor transmit any (personal) information.

We are the sole owners of the information that you provide voluntarily by e-mail or any other means used by us for communicating with you. We will NOT release this information to anyone

We will use your information to respond to you, regarding the reason you contacted us. We will not share your information with any third party outside of our organization, other than as necessary to fulfill your request, e.g. to help with in-app purchases or to implement a requested feature.

Unless you ask us not to, we may contact you via email in the future to tell you about specials, new products or services, or changes to this privacy policy.

Your Access to and Control Over Information

You may opt out of any future contacts from us at any time. You can do the following at any time by contacting us via any of the means available:
  • See what data we have about you, if any.
  • Change/correct any data we have about you.
  • Have us delete any data we have about you.
  • Express any concern you have about our use of your data.


We are using third party services to communicate with you, such as online forums, e-mail and similar. As such the information you give us is accessible according to their respective policies.

Once your request is fulfilled, the information is discarded, but may remain accessible according to policies of the service you used to contact us, e.g. the forum post will remain visible in the thread, e-mail message will be archived, but not deleted, etc.


Our Privacy Policy may change from time to time and all updates will be posted on this page.

If you feel that we are not abiding by this privacy policy, you should contact us immediately via email.

Friday 5 October 2012

Velis auto brightness changelog

4.65.234 (09.09.2017)

  • Fix for crashes in Androids < 5 (sorry)
  • Fix for direct sunlight issues
  • Fix for widget graph getting cleared
  • Fix for Android 8 notification

4.65.233 (27.08.2017) 

  • Fix for very high sensor values (direct sunlight) 
  • Fix for excluded apps sensor value override (high value) 
  • Fix for profile button menu colours

4.65.231 (21.08.2017)

  • Fix for Samsung glitch in excluded apps detection
  • Fix for settings mode
  • Fix for notifications freezing under full sunlight
  • Updated russian translation

4.65.226 (17.07.2017)

  • Updated italian language
  • Top activity check uses much less battery now (Android 5 and above)
  • Major remodel of internal workings. Also less battery usage
  • Setting: brightness update interval: Reduce number of updates which would reduce battery usage
  • Setting: Turn VAB on when screen turns on
  • Setting: enable direct sun screen brightness boost
  • (hopefully) more resilient service (should be stopped by system less often)
  • When change is applied from notification, it's not lost on reboot any more

4.57.215 (09.06.2016)

  • Minor fixes

4.57.214 (21.04.2016)

  • Default camera API back to V1 (V2 gave too much trouble)
  • Navigation drawer always open on wide enough displays

4.56.212 (21.02.2016)

  • Split settings to Basic, Advanced
  • Updated Russian language

4.56.210 (8.2.2016)

  • Fix crashes (wizard, theming)
  • Add support for Android Camera API v2 (might coexist with other camera apps better)
  • Updated Romanian language

4.55.207 (8.1.2016)

  • Fix for excluded apps in 5.0
  • Widget would report tasker content not purchased when it in fact was
  • Other minor fixes

4.55.205 (14.09.2015)

  • Some minor tweaks and fixes

4.55.204 (09.09.2015)

  • FIX: Excluded apps work on Android 5.1 and newer (requires special permission)

4.50.202 (04.9.2015)

  • VAB now works in lock screen on lollipop
  • Better superdim performance
  • Theming

4.21.194 (19.5.2015)

  • FIX: Excluded apps bug

4.21.193 (16.5.2015)

  • FIX: Users on lollipop with camera as sensor will now have brightness for lock screen set to Screen-on sensor value override instead of fixed 80%
  • Added setting for required number of touches (was fixed to 3) to refresh screen brightness when steady screen is on
  • Add setting for brightness when VAB turns off for excluded apps
  • FIX: Theming for buttons
  • FIX: RTL did not work on manually selected RTL language
  • FIX: new app install no longer shows the apply / cancel buttons

4.20.192 (22.4.2015)

  • FIX: Best I can get for lollipop lock screen (sorta works)
    My ultimate (and probably final) attempt at fixing lollipop lock screen. I have researched *everything* I could think of, nothing worked.
    There's no way that I know of that can properly handle this, so I made an extremely ugly hack: I used system AB for those that have it and set screen to 80% brightness for everyone else (those on cameras as sensors). I'm so angry at Google right now and their API breaking changes. :mad:  Total waste of my time, instead of adding semi-cool features, I have to slave around with this.

4.19.191 (21.4.2015)

  • FIX: Wrong overlay type after lock screen (various things didn't work)

4.18.189 (20.4.2015)

  • Yet another try at fixing lollipop lock screen
    • This should also fix issues for delayed camera first read after leaving lock screen
  • FIX: Additional brightness doesn't work
  • FIX: Notification removed from lock screen
  • FIX: Transparent icon removed from lollipop status bar

4.17.188 (15.2.2015)

  • Fix colours

4.16.187 (5.2.2015)

  • Fix unresponsiveness in lollipop

4.15.183 (26.1.2015)

  • Fix flickering lock screen on some devices
  • Fix notification text color

4.13.182 (23.1.2015)

  • Further fixes for lock screen

4.12.181 (20.1.2015)

  • Fix excluded apps in lollipop
  • Fix screen-on responsiveness when Lock screen is NOT among excluded apps
  • Fix screen-on override (sometimes didn't work)
  • Fix non-responsive auto-brightness in some situations
  • Fix crashes at app start

4.10.180 (18.1.2015)

  • Portugese by renatohm
  • Fix lollipop issues
  • Move to iab v3
  • Move to Android Studio
  • All images in app are now vector

4.01.177 (4.6.2014)

  • New translation: greek by pugsang
  • FIX: steadyscreen functionality now much more stable

4.00.175 (7.4.2014)

  • FIX: Notification didn't properly update confirm / cancel button when they were pressed
  • FIX: There were some crashes reported through play store. This fixes them

4.00.168 (6.3.2014)

  • When screen is touched, brightness is not updated for specified time (a new setting - also in wizard)
  • The above setting isn't active when VAB is frontmost app
  • Notification is updated at least every 5 seconds (is now more precise)
  • Unconditional additional brightness
  • Additional brightness accepts negative numbers (will decrease brightness)
  • FIX: Wizard back button now actually works + wizard page count fix
  • FIX: After wizard, settings screen is refreshed to show selected values properly

3.60.166 (24.2.2014)

  • Collapsible settings groups for easier navigation
  • Excluded apps memory and performance improvements
  • FIX: when sensor returned 0, some app functions didn't work correctly
  • FIX: Sometimes changing profiles didn't work correctly

3.60.164 (15.2.2014)

  • Added option to try and reduce erratic sensor readings in some devices (most notably SGS 3 and Note 2)
  • Turning off interactive notification for Android 4.3 and up is now a regular settings option
  • FIX: manual graph edit didn't work for many locales

3.55.162 (11.2.2014)

  • Menu key now opens menu
  • App titlebar now displays that there's a menu to be opened (and opens it)
  • Floating point lux values: much greater precision for low sensor readings
  • Some battery usage optimizations
  • Camera now respects grab interval setting
  • New language: dutch, thanks to Maardiweb

3.55.158 (7.2.2014)

  • Completely redesigned reading interpolator. Less battery usage, fixes a ton of smoothing-related bugs
  • FIX: If service is turned off, cameras will now stop reading
  • FIX: Stopping VAB now completely removes the overlay. Should reduce issues on some devices when VAB was on and still held the brightness

3.55.153 (11.11.2013)

  • Minor visual glitch fixes
  • Interactive notification - only show the buttons once a custom brightness is set
  • No notification option for Android 4.3+
  • Vietnamese by Vu Hien

 3.50.149 (1.11.2013)

  • User interface via fragments

3.15.142 (16.10.2013)

  • A fix for faulty EXIF records in some phone models
  • Chinese language by Jinran Lin

3.15.141 (8.10.2013)

  • Interactive notification
  • Launcher widget can now also render transparent

3.10.135 (23.6.2013)

  • Kernel sensor reader now safer + 0 reading is a valid reading
  • Main screen VAB on/off now properly reflects service state
  • Excluded apps now displays previously selected apps at the top of the list
  • Launcher widget text forced to white

3.08.133 (22.6.2013)

  • FIX: colors in excluded apps list would be strange on some phones
  • Overlay no longer destroyed on screen off to eliminate delay for screen-on
  • SGS 2 now has a kernel sensor reading mode which enables the entire sensor range instead of just 1, 10, 100, 1000

3.05.122 (9.4.2013)

  • When superdimming threshold is set to 100%, it becomes the only method of adjusting screen brightness. Makes brightness adjustments much smoother on some phones (SGS3, GNex 4, etc). Since this method is completely linear, using a brighter preset is recommended or the screen might become too dark.
  • Completely remove brightness window when disabling. Should fix problems with system brightness when VAB is disabled on some phones.
  • Fix graph presets so that graph adjustments at right edge behave normally
  • Fixed strange graph behaviour at graph edges
  • Added graph adjustment sensitivity setting for more precision with graph adjustments
  • Draw superdim threshold in graph (non-user-interactive for now)

3.00.118 (27.3.2013)

  • Fix device exclusions due to camera permission
  • Settings wizard no longer clears saved profiles
    • Settings wizard no longer starts multiple times on new installs
    • Fix sensitivity presets for settings wizard
  • S-curve graph no longer renders beyond graph boundaries
  • Updated translations: slovak

3.00.114 (24.3.2013)

  • Reduced smoothing intervals to reduce flickering on high-end phones
  • Graph period must not be set to 0 (if it's 0, it crashes)
  • Preliminary camera support. See XDA thread for more info

2.82.101 (15.2.2013)

  • Fix for app service disabling itself when a popup is active

2.81.101 (11.2.2013)

  • Custom app language selection
  • Excluded apps (will disable VAB when an excluded app is on top)
  • Super dimming: in addition to backlight also add a screen filter for deeper blacks
  • Separate setting for smoothing time when dimming
  • Android 2.1 & 2.2 compatibility fix (store will still never work below 2.3)

2.81.95 (9.2.2013)

  • Revert to 2.31.84 (13.1.2013) - before screen filter - to resolve some issues
  • All updates since 2.31.84 temporarily disabled
  • Will be added again as they are eliminated as possible causes for the issues detected

2.81.94 (9.2.2013)

  • Android 2.1 & 2.2 compatibility fix (store will still never work below 2.3)
  • Excluded apps list FC fix

2.81.92 (9.2.2013)

  • Fix excluded apps dialog (loads apps smoother)
  • Add superdim activation brightness check
  • Updated translations: persian, slovene

2.80.90 (2.2.2013)

  • Custom app language selection
  • Excluded apps (will disable VAB when an excluded app is on top)
  • Super dimming: in addition to backlight also add a screen filter for deeper blacks
  • Separate setting for smoothing time when dimming
  • Launcher widget 4 slots wide by default

2.31.82 (12.1.2013)

  • Much faster brightness graph rendering (less CPU usage on main screen)
  • Fixed smoothing "hiccups". Graph is now buttery smooth
  • Only use samples after screen-on
  • Add an s-curve graph to the presets
  • Updated translations: slovak, slovene

2.30.80 (6.1.2013)

  • Launcher widget
  • Fix graph adjustments at graph edges
  • Clear settings to default (when wizard starts)

2.20.76 (2.12.2012)

  • Fix for landscape
  • Fix for sensor getting stuck
  • Fix for brightness remaining even when service is disabled

2.20.74 (21.11.2012)

  • App will load custom translation strings (helps translators do their work, see app homepage for instructions)
  • Updated translations: norwegian, italian, slovene
  • Removed requirement for light sensor (will show app to sony xperia users)

2.20.72 (14.11.2012)

  • Settings wizard
  • Service will stop after a minute if auto brightness is disabled
  • Support for proprietary sensor solution on Sony Xperia
  • Better LTR language support
  • Updated translations: german, persian, slovak, spanish

2.01.64 (30.10.2012)

  • Added links to manual and changelog to app menu
  • Screen_on sensor override value (going from light to dark room)
  • Smoothing override setting (when light change is too big, it will just skip to new value)
  • Setting to update system brightness setting
  • Fix for proximity sensor action
  • Fix (hopefully) for graph remaining stuck at some reading
  • Better logging (long-press proximity reading values to set level 0 - 9)
  • Manual graph editing as text
  • Added display of changelog at program start
  • Updated translations: slovene, german
  • Added language: hungarian

2.00.61 (26.10.2012)

  • Fix for in-app billing
  • Updated translations: german

2.00.59 (26.10.2012) - XDA thread only

  • Tasker / locale support
  • In-app billing
  • Updated translations: slovene, german, spanish

 1.20.55 (22.10.2012)

  • A first feeble attempt to prevent service terminations at night
  • Better proximity sensor handling
  • Enabled proguard to make the apk smaller and the code a bit faster
  • Intermediate publish to prepare for tasker and in-app store
  • Added language: russian, japanese, polish
  • Updated translations: slovak, slovene

1.20.49 (15.10.2012)

  • Updated translations: french, norwegian, german
  • Remove strings that won't be used again
  • Fix "track light in graph" buttons appearing without modifying graph
  • Minor fix for about dialog
  • Added language: persian

1.20.46 (13.10.2012)

  • Updated translations for spanish and norwegian
  • Fixed some untranslated strings (new strings for translators)
  • Added about dialog to check current version
  • Applying graph point now eliminates close neighbours and duplicates
  • All new custom settings screen - should be more readable
  • Supported language: french

1.10.40 (9.10.2012)

  • Further optimizations to reduce battery consumption
  • No longer updating android brightness (was just a cosmetic which turned out to use lots of CPU)
  • Reduced last sensor value save interval to one minute to save even more battery
  • Supported languages: slovak, spanish, norwegian (classic and bokmål)


1.10.37 (8.10.2012)

  • Reduced graph size in landscape mode so that it fits on screen
  • Supported languages: german, lithuanian

1.10.35 (7.10.2012)

  • StartSensors checks for screen off - eliminates sensor time when screen is off
  • Save current sensor value in case of service shutdown - load it when service restarts
  • Change System handler text to "Disable system handler". Previous meaning was just the opposite
  • Choosing a preset or profile now refreshes graph again
  • Supported language: italiano


1.10.34 (5.10.2012)

  • Sometimes in low light conditions brightness would drop to minimum without any apparent reason
  • Fix a situation when (un)plugging power won't immediately adjust brightness. 
  • Fix for service activation switch which didn't properly turn off system auto brightness.
  • Fixed class that required Android 2.3 - back to 2.1 support 
  • Translation support
  • Supported language: slovenian

1.10.32 (4.10.2012)

  • No more of no sensor reading
  • Change app description (again) to please competitor

1.10.31 (3.10.2012)

  • Battery usage fix. This should significantly reduce battery usage

1.10.26 (2.10.2012)

  • Fixed sensitivity threshold
  • Removed unnecessary calculations
  • Optimized moving average routine
  • Lower power consumption
  • Change app description to please competitor

1.10.24 (1.10.2012)

  • Fix FC at app first start
  • Fix averaging function

1.10.21 (1.10.2012)

  • Profiles (save the brightness graph under your own selected name)
  • Jitter control to prevent excessive brightness updates
  • Brightness smoothing to make the transitions smoother
  • Minor bug / functionality fixes

1.0.20 (30.9.2012)

  • initial Google play release

1.0.0 (12.8.2012)

  • development start

Friday 28 September 2012

Velis auto brightness

Get the fun back to your auto brightness...

Free download link: Google play store

Strings for translations - all translation help appreciated. The link points to a .zip archive containing all localizations. The base for translations is english text found in "values" directory. Please send the translated strings to my e-mail. Basic knowledge of xml needed: translate only values, not ids. Use plain text editors such as notepad.exe, gedit or kate. Make sure the file is UTF-8 encoded before sending it back.
You can test your translation before sending it to me by placing your translated strings.xml into the phones /sdcard/ directory (root of external storage). The app will detect if such a file is present and load it. Note that currently the menu and some arrays are not translated in this way, but most of the strings should work just fine.

For usage, please see the manual.

Please see XDA homepage about language support. Any translation help most welcome!

Velis auto brightness aims to provide the best possible brightness experience by using your devices sensors to determine the environment you're in. You have complete control over how much brightness will be applied for any given light condition, from selecting the sensors used to fully customizable brightness graph. This is a replacement for system provided auto-brightness functionality usually found in Settings / Display / Brightness

  • Initial configuration wizard for an easy start
  • User-selectable sensors: light, proximity (cameras planned soon)
  • Supports custom sensors on phones such as Sony Xperia
  • Brightness presets for every taste and screen
  • Profiles (save the brightness graph under your own name)
  • Fully customizable brightness graph to fit your needs or cover your sensor’s faults
  • Extensive sensitivity adjustments (light change threshold, smoothing times up / down, boost threshold)
  • Superdimming to make those shades really dark 
  • Excluded apps (will disable Velis Auto Brightness when they are on top)
  • Launcher widget with on/off button, profile select button and a brightness graph
  • Tasker / Locale support for many sensor readings and app settings
  • Convenient in-app store for premium content (some tasker and widget functionality) and developer support
  • Custom app language
  • Additional brightness when charging
  • Only uses sensors when screen is on conserving battery
Battery consumption notice: This app has been and still is rigorously tested against battery consumption. The only things consuming battery are graph updating (main app screen) and Tasker / Locale conditions for lux, brightness readings (they are frequent events).
However, some phones - most notably some custom ROMs on SGS 2 - will still report this app as the highest battery user even though the battery does not drain any faster than without this app. Please verify your actual battery usage before complaining about the app being listed as a big consumer.

Tasker plug-in / Locale plug-in: Provides conditions for screen on, calculated light reading, proximity sensor reading, calculated brightness. Exposes many settings to locale / tasker for detailed adjustment from these managers. Some of this functionality is premium content available through in-app purchase.

XDA thread (best for support) here.


Activating multiple auto-brightness applications will not produce expected results so make sure only Velis auto brightness is active while you test it. This file is provided AS IS - without any warranty. The autor will not be liable for any (un)imaginable inconveniences, including, but not limited to your phone frying or your screen starting to shoot launcher widgets at you. :)


This app is available in following languages

* English - base language
* Chinese by Jinran Lin
* Czech by Holly Hell
* Dutch by Maardiweb
* French by Pims83
* Italian by siggey
* German by Chef Koch
* Greek by pugsang
* Hungarian by XT69
* Japanese by Magus
* Lithuanian by cukierkas
* Norwegian by MrMastodon
* Persian by Alireza Afkar
* Polish by trur3
* Portuguese by renatohm\n
* Russian by Pavel Utochkin
* Romanian by rapttorx
* Slovak by kubics
* Spanish by UnderXP
* Vietnamese by Vu Hien
* Slovene

Thanks to all the translators for their hard work.


WRITE_SETTINGS: Required to turn off system auto-brightness. This is for your convenience so that you don't have to go to system settings manually turning off system auto brightness
RECEIVE_BOOT_COMPLETED: Required for starting the service at bootup so that auto brightness actually works without manual program start.
SYSTEM_ALERT_WINDOW: Required for auto brightness to actually operate
GET_TASKS: Needed to detect current top activity for app exclusion list and proper screen filter operation
CAMERA: Determine environment brightness through cameras.
BILLING: Required for in-app store


Main screen




Launcher widget

Friday 16 March 2012

Preprosto in učinkovito

Naši politiki blazno radi govorijo o sivi in črni ekonomiji, malo manj pa jim gredo od rok ukrepi, ki bi te probleme zmanjšali. Naj bom vsaj malo v pomoč:

Ukrep številka 1: Omogočiti ljudem "male posle", na primer do letne višine 10.000 EUR (povsem arbitrarna številka, ki sem jo potegnil iz enega temnega prostora). Za te posle državljan ne potrebuje avtorske pogodbe, firme ali podobne zadeve. Vse, kar potrebuje je sledeče:
  1. spletni portal e-uprave, na katerem lahko vtipka "fakturo" za opravljeno delo
  2. spletni portal naredi fakturo, pripravi ustrezen sklic za nek državni račun ter obračuna fiksen davek in pošlje te podatke DURSu
  3. davek je na primer enak davku od dobička pravnih oseb
  4. kupec malega posla nakaže denar
  5. država nakaže denar z odštetim davkom izvajalcu posla
Posel zaključen, davki obračunani, vsi so srečni, nobenih komplikacij, država pa ima garancijo, da je bil mali posel sklenjen zakonito in transparentno. Seveda taki mali posli niso možni med subjekti, ki imajo obstoječa delovna ali drugačna poslovna razmerja.
Precej laže kot sedaj, ko je nekatere male posle v bistvu nemogoče sploh izpeljati, ne?

Ukrep številka 2: Uvedba družbeno koristnega dela za vse prejemnike nadomestil za brezposelnost.
Vsak, ki prejema "plačo" od zavoda, bi moral opravljati družbeno koristno delo oziroma vsakršno delo, ki bi ga zavod pač našel zanj. Lokalne skupnosti bi razpisovale dela, zavod za zaposlovanje pa bi razporejal ljudi na ta dela.
Delo bi bilo obvezno 4 dni v tednu, en dan bi bil na voljo za razgovore o zaposlitvi, vendar bi brezposelni moral prinesti dokazila, da je ta dan dejansko bil na vsaj enem razgovoru.
Ta ukrep bi:
  1. takoj uničil vso črno ekonomijo, saj njeni izvajalci ne bi imeli več možnosti izvajanja del na črno
  2. hkrati bi močno povečal željo teh ljudi za iskanjem zaposlitve ali ustanovitvijo svojega podjetja
  3. preprečil bi "zaposlitveno zaustavitev" brezposelnega, saj bi bil brezposelni ves čas aktiven in tako ne bi zapadel v melanholično brezdelje
  4. z raznimi delavnicami bi lahko delali tudi turistične spominke in podobno ter tako dosegali sinergije z gospodarskimi panogami
  5. naša mesta in vasi bi se kar svetili, tako dobro bi bili pometeni
Ukrep številka 3: Prekvalificirati odvečne zaposlene v državni upravi v inšpektorje
Zaradi mene tudi nezaposlene, vsekakor pa bistveno dvigniti število inšpektorjev.
Tako bi poleg obstoječega nadzora lahko izvajali tudi sledeče:
  1. finančna policija - kako ima lahko nekdo ob plači x tri vile v Monaku in 15 podjetij v lasti?
  2. preverjanje sive / črne ekonomije - inšpektor en mesec dela pri nekem izvajalcu in sledi vsem poslom v tem času ter kako izvajalec izdaja račune zanje. V primeru odstopanja (predvidoma navzgor) od pretekle prakse pri tem izvajalcu naslednji mesec drug inšpektor (nikoli isti), s čimer se najverjetneje potrdi, da je v preteklosti izvajalec dejansko goljufal. Pa preteklost sploh ni tako pomembna: tak izvajalec bi pač imel pogoste tovrstne inšpekcije, dokler se ne bi "navadil" normalno izdajati račune za svoje delo.
  3. preverjanje nadur, dežurstev in podobnih generatorjev raznih dodatkov k plači pri zdravnikih, sodnikih in drugih javnih uslužbencih.
  4. itd, itd.
Ukrep številka 4: plačilna disciplina
Vsaka faktura prijavljena na DURS. Vsaka zavrnitev fakture prav tako prijavljena na DURS. Ob poteku roka za plačilo v primeru neplačila DURS avtomatsko trga dolžniku. Število iteracij in trajanja zavrnitev omejeno, v primeru preseganja avtomatska in takojšnja mediacija.

To so samo štirje ukrepi, proti katerim se celo naši slavni sindikati ne bi preveč upirali, hkrati pa bi povečali BDP države še v letošnjem letu. Ne, to sem slabo povedal. Povečali bi BDP TAKOJ! Da sploh ne govorim o prilivih v državni proračun.

Zakaj tega ne moremo imeti?

Saturday 10 March 2012

Increasing transaction performance and getting rid of deadlocks caused by high transaction count

If you're seriously into database applications, you are sure to have bumped into a customer that was really big. Like so big that their server reached a point where it was no longer capable of serving all the transactions requested by the software / users. Personally reaching this point is a genuine nightmare for me: monday everything is fine, everybody works normally and we are happy. Then they install that damned robot / new warehouse / whatever which increases the transaction count for the system. So tuesday all hell breaks loose: everything people try to do takes ages and more often than not reports the deadlock victim error. Naturally, we are no longer happy.

Solving such situations requires expensive performance tuning software, lots of analysis and optimizing query by query so that you can lift at least some burden off the poor server which is of course still struggling, but *just* not so much that everything would halt any more. To quickly recap your performance tuning options (the real purpose of this article lies beyond this list :-) ):
  1. Indexes
    1. Adding a good clustered index for that most used aggregate query will work wonders usually.
    2. For less important queries add normal indexes. 
    3. But beware: adding too many indexes kills your insert / update performance because the SQL server needs to update too many things for one addition or correction in the database.
    4. Also bear in mind that having single - column indexes will not really help much with multi-column where or group by statements. Sure - it helps a little, but nowhere near what a proper multi - segment index would do for you here
    5. Recent SQL servers also have the capability to extract all the data for a query just from an index. So if you have an (aggregate) query which only uses a few of the table columns, usually creating an index just for this query is not such a bad idea, especially if you're running said query all the time
  2. Locking
    1. You should be very careful what you lock and when
    2. The most common culprit are usually configuration tables - if you store application config in a table. This table is accessed for pretty much anything all the time and moving all these accesses out of transactions or using with(nolock) hints helps tremendously
    3. The next most common lock targets are link tables - the tables that establish data relations. Like this delivery item was originally requested in order #xxx. Depending on application design you will most likely have at least one such table in your system. Also needs special care, but unfortunately can't really be optimized since it must be kept in the transaction for data consistency.
    4. Anyway, you should let the SQL server manage locks at a level as fine as possible so that there are as few as possible lock races
  3. Query optimization
    1. Can't really say much about this since it's query - dependant, but I have seen some really yucky queries in my day
    2. Usually a simple rewrite of a nasty query will decrease query execution time multiple - fold
    3. Take care not to use multiple (basically equal) subqueries - rather use them in a join (and a group by)
    4. Joins are (almost) always better than subqueries
    5. Dynamic views (select from select) are also better to be avoided if possible though sometimes they are the basis for your query
    6. Once you detect a query that needs optimization, you optimize it and make sure indexes in the respective tables cover your query's needs
    7. General rule of thumb is that there should be absolutely no table scans executing the query and possibly no index scans. Scans take time, seeks do not!
    8. If you can't think of a way to optimize a really bad query, drop me a mail. For a modest fee I will do this for ya }:-)) (Seriously though: see the donate button at the bottom of the page and don't write without clicking it)
This is about it. The above procedures will usually give you good results but they take many hours of analysis and optimization and thus take valuable time of your programmers who could be better spending their time creating new (bad) queries for new software functionality.

There are also two programmatic options you have at your disposal which will do a lot more general good with less effort for your programmers - since they affect all transactions ever issued throughout your system. The only prerequisite here is that your application is well designed and you actually have access to code that starts / finishes / aborts transactions:

The first option is to simply catch deadlock errors and restart the transaction automatically. Aside from taking even more time, your user will never know that a deadlock even occurred. However, the SQL server will know since this will put even more stress on it - and don't forget: you're having the deadlocks because you placed too much stress on the server in the first place.

The second option is to serialize your transactions. This one is the purpose of this article. You see, until yesterday we at the company I work for always went for performance tuning / optimization. However yesterday I developed a really simple solution which I didn't really believe would solve anything. I just hoped it would do *some* good for the poor server at our client's. Boy was I in for a treat :-)
I was at the client's two days ago and I can testify that their server was just way too loaded. I have personally started 10 transactions. Of those, 5 went straight through in less than a second (normal time), 3 deadlocked after more than 30 seconds (definitely bad) and 2 went through in more than 30 seconds (meaning somebody else probably got the deadlock). Disk time was at 100% all the time and CPU was only low because the CPU was waiting for the disks. All that on one of the most powerful database servers I have ever seen deployed at our customers. The situation was just horrible. All because we installed some automatic data transformations to support their new huge automatic warehouse and a few of packaging robots.
Once I installed the serialization code, I first thought the entire system crashed. There was no activity for two minutes or so. Only after this initial period where server was so stumped that it simply couldn't do anything, things started rolling:Transactions started to come in in hundreds per minute as all the automated jobs started doing their work that failed in their previous attempts due to deadlocks. For the first fifteen minutes all I could look at was that flood of transactions being mostly nicely serialized. But then everything just stopped again - revealing that there are actually only about 20 transactions per minute. Once I reached this state, the server was at practically 0% CPU usage and 0% disk time - just smooth sailing from now on. Total, entire and unyielding success!!!!
So it turns out that it's not the server that is too weak. It's just that SQL server tries to accomodate all users by running multiple transactions in parallel, but that leads to locking and lock waiting and transactions that should take milliseconds start taking seconds. During that time new transactions come worsening the situation further - until the entire thing slows down to a deadlock infested crawl.

OK, enough of blabbing, here's what I did:
The first prerequisite was that I needed to add some code just before calls to start / stop transactions. All that code does is to call a stored procedure on the SQL server just before it initiates a transaction and again calls the same procedure just after it finishes / aborts the transaction. This is super important: doing this inside a transaction would just kill the purpose because the locking would be done on the scheduling table as well.
Anyway, really simple, really easy. The stored procedure is designed so that it will return a "transaction ID" as well as "permission" to start transaction. The "permission" part of the result is actually number of transactions that will be allowed to start before this one so you can even notify the user while this particular transaction is waiting to be started.
The sample function itself has three possible input value forms:
  1. "Announcement" null - I want to start a new transaction, give me an ID and queue #. When Queue # reaches 0 I can start the transaction
  2. "Is it my turn yet?" transaction ID (returned by previous anouncement call) - I'm waiting to be allowed to start. What's my queue #?
  3. "I'm done" negative transaction ID - I'm finishing / aborting transaction

Of course you can do this any way you like, my particular implementation is done like described, but it's in no way perfect. That's the beauty of this method: you can make your transaction scheduler any way you want as long as you serialize at least some transactions.

The general concept of this solution is this:
First we assume that all transactions are equal and that they should be executed in order (as opposed to simultaneously) to lessen the locking stress on the server. Then we eliminate any transactions that appear dead and all transactions that are classified as long taking. The method assumes that most transactions are very short and attempts to serialize those while it leaves the user-prompt infested ones take as long as they want. As explained above, it turns out that the locking stress really is stressful on the server. I could not believe the results when I saw what was going on, but the final results show that serializing the fast transactions helps more than just a lot.

A more detailed description:
Before starting a transaction, we add its announcement into a special table. Since we're doing this outside the transaction, the table is available to all at all times. A stored procedure makes sure that the entire thing runs on the server and is fast because of this. I'm running the second form (is it my turn yet?) every 100 milliseconds (on each client) and have observed no ill effects whatsoever. In order to keep the entire thing fast, I remove all records older than 15 minutes so as to keep the table size as small as possible.
The stored procedure makes sure the transaction is inserted into the queue (announcement), checks current queue # (announcement and is it my turn yet) and marks transaction as still alive and also marks the transaction as finished when called with negative transaction ID (I'm done).
Just in case some transactions take too long, the procedure will ignore them and allow other transactions to run in parallel and also if one transaction is no longer checked upon, it will also be ignored. This approach makes sure that a single transaction can't be blocking the entire system just because it's slow - small transactions just run and hope that the large transaction won't block them (turns out this is extremely rarely the case).
The client registers the transaction using the first call form and then waits in a loop until the Queue # drops to 0 for the transaction. Then transaction is ran as it always was and when it is finished, the client also reports that it is finished.

So if you now already modified your database access library to include stored procedure call as described above, all that is missing is the stored procedure and related call. You should now be running the new application just to see that nothing changed. Once the stored procedure is added, the magic should begin. I have included the two statistics selects at the bottom just for the nice side-benefit (transaction statistics) :-)
This solution is in MS SQL T-SQL language, but I suppose a conversion to any other database should be easy.

The helper table:
create table transaction_serializer (
  id int identity(1,1) primary key,
  time_inserted datetime null,
  time_queried  datetime null,
  time_executed datetime null,
  time_finished datetime null
create index transaction_serializer_i1 on transaction_serializer (time_finished, id)
create index transaction_serializer_i2 on transaction_serializer (time_queried)

The stored procedure:
create procedure serialize_transaction(@transid int)
as begin 
  set nocount on
  set ansi_warnings off
  declare @transok int

  --Remove 15 minute old records to keep this scheduler table small and fast
  delete from transaction_serializer where time_inserted < dateadd(mi, -15, getdate())
  if @transid < 0 begin
    --Transaction done
    update transaction_serializer set time_finished = GETDATE() where ID = -@transid
    set @transok = 0
  else begin
    if @transid is null
      -New transaction
      insert into transaction_serializer (time_inserted) values(GETDATE())
      set @transid = @@IDENTITY
    -Determine queue# for transaction
    select @transok = COUNT(*)
      from transaction_serializer
     where time_finished is null and id < @transid --How many transactions in queue before ours
       and isnull(datediff(ms, time_executed, GETDATE()),0) < 2000 --Eliminate long taking transactions
       and isnull(datediff(ms, time_queried,  GETDATE()),0) < 2000 --Eliminate seemingly dead transactions

    if @transok = 0 begin
      --This transaction first, let's start it
      update transaction_serializer set time_executed = GETDATE(), time_queried  = GETDATE() where ID = @transid
    else begin
      --Just mark the transaction still alive
      update transaction_serializer set time_queried  = GETDATE() where ID = @transid
  --transid contains transaction id which the client then uses for querying queue # and marking transaction as done
  --transok is 0 - if the transaction can be started or positive number which tells us that our transaction is still waiting
  select @transid, @transok

The additional selects to retrieve statistics:
select *, datediff(ms, time_executed, time_finished), datediff(ms, time_inserted, time_executed) from transaction_serializer
select count(*) as NumTrans, 
       max(datediff(ms, time_executed, time_finished)) as MaxTransTime, 
       avg(datediff(ms, time_executed, time_finished)) as AvgTransTime, 
       sum(case when datediff(ms, time_executed, time_finished) > 2000 then 1 else 0 end) as NumOfLongTransactions,
       max(datediff(ms, time_inserted, time_executed)) as MaxWaitTime,
       max(datediff(ms, time_inserted, time_executed)) as AvgWaitTime
  from transaction_serializer

Now you know that implementing this just saved your ass with the client. So for your convenience you can express your gratitude by clicking the following button. Don't be shy, you know I just saved your company thousands in costs of performance tuning :-) In case you're feeling stingy at least click a link in the banner on the right side of this page.

  For possible further inquiries drop me a mail at jure dot erznoznik at gmail dot com.