I bumbed by change to Odoo website and started to look their offering. At first clance Odoo seems to target to enterprise market by aiming to be an alternative to Oracle and Salesforce as a business management software. But once I started to look a bit deeper I noticed that you can use the system for any size of businesses.
Odoo has a composable “apps” concept where you first you have the Odoo foundation and then you choose which apps you want use.
Different Apps on Odoo
Company
Odoo founded in 2005 is a Belgium-based provider of open-source-based business software that ranges from inventory management and ERP to human resources and CRM software, marketing tools and more. Odoo has raised a total of $439.5M in funding over 5 rounds. Their latest funding was raised on Jun 8, 2022 from a Private Equity round. They have around 2000 employees growing ~50% per year. Odoo’s estimated annual revenue is currently $234.6M per year.
Technology
Odoo is typical multitenant, three-tier architecture written in JavaScript and Python. Data storage is PostgreSQL.
Odoo in 90 seconds
Odoo’s elevator pitch
Customers
Used by over 5.000. 000 users worldwide ranging from startup companies (1 user) to large enterprises (300,000+ users). About 90% of Odoo’s customer base takes the free tier, he said, with only 10% taking the paid, proprietary tier. But with 7 million users, that is enough to run the business at a profit big enough that it can continue investing in growth without giving away more equity.
Pricing
Odoo Community edition is available for free but of course you need to put price on hosting and operations. Their SaaS offering, Odoo Enterprise edition costs $20/user/month (annual billing) or $25/user/month (monthly billing). On top of that you can add different Apps that raises the price.
Summary
Is it better than Salesforce, SAP, Dynamics, etc.? Probably not. Is it good enough given the price point and flexibility, for smaller businesses? Looks like yes.
It’s only a preview feature in Canary builds right now, but Chrome is adding a new Recorder panel to its DevTools which lets you record and replay a string of actions on a page (including under simulated slow network conditions). You can also measure the flow and get a performance trace for analysis.
I noticed that WordPress and WordPress Multisite on Azure does not perform well. It seems that anything written in PHP is not the first class citizen on Azure and PHP runtime as well as MySQL behaves differenly on Azure than running it on VM or Docker.
I was not able to make WordPress as fast as it would be on VM but I got close. Please notice that I am running App Service under Windows Operating System. If you have change to run this under Linux you will likely get much better performance and some of the tips below may not be relevent for you. In any case fine tuning these settings are always solution specific but if you have performance problems I hope my findings helps you.
Step 0 – App and SQL plans
App Service You should run the App Service in minimum P1V2. Everything smaller in a bigger solution becomes slower. This gives 210 total ACU 3.5 GB memory for the app.
Azure Database for MySQL server
Gen 5 with 100 GB and 4 cores seemed to work for me. I noticed that there was not much of difference if you choose Basic with 2 vCores. If you don’t need large storage I recommend trying out Basic first but notice that you cannot scale from Basic to General Purpose with a click of a button. It requires moving db’s manually.
Step 1 – App Service Settings
Changes Made:
PHP version 7.4
Set the Platform as 64 bit
Set HTTP-version to 2.0
Set the site to ‘Always on‘
Turn Off the Affinity Cookie
Step 2 – Extend PHP.INI
Open the solution in Kudu or FTP client and create new folder at d:\home\site\ini on your app structure. Under new ini -folder create settings.ini and add following settings:
wincache.maxfilesize – Defines the maximum allowed size (in kilobytes) for a single file to be cached.
memory_limit=2048M – This sets the maximum amount of memory in bytes that a script is allowed to allocate.
upload_max_filesize, post_max_size, max_execution_time, max_input_time – You may not need this. I got some bigger file execution operations in relation to a WP plugin that required extend size and execution times. Not exactly related to performance.
output_buffering – I don’t really understand why this is set on Azure. App seems to run better if it is disabled?
After adding the settings.ini under d:\home\site\ini\ folder open App Service > Configuration > Application Settings and the folder to the key called PHP_INI_SCAN_DIR=d:\home\site\ini\ like this:
Save and restart the App Service. Now you should have custom INI for your app where you can adjust default PHP settings.
You can verify that your settings are correct by creating phpinfotest.php with <?php phpinfo(); ?> in it and uploading it to the webroot. Then on your browser you can see this file and see all your settings.
Redis Object Cache and App Service Local Caching
I have tried both of these and neither them helped me but it might help on some installations. So I will write few words about them
App Service Local Caching
The Azure App Service Local Cache feature provides a web role view of your content. This content is a write-but-discard cache of your storage content that is created asynchronously on-site startup. When the cache is ready, the site is switched to run against the cached content. Enabling local caching will change how the storage works for your app service. This is only recommended for more static WordPress instances and not for WordPress instances that have new posts or pages.
To enable it add these settings to your application settings
I have heard and read this is great setting on some solutions but for me performance got 10 x worse with local caching. So I drop it.
Redis Object Cache
Object caching allows your web application to cache the results of queries as objects in low latency memory based storage. But this is also something that may not work for your solution. I did not have good luck on my solution, on my instance speed got 10-15% slower after enabling Redis. There are a few caveats to using the Redis Object Cache approach on WordPress. The caching mechanism does not work well if you have a lot of plugins and themes installed. This is due to the fact that all their data would need to be cached as well with Redis. But it is worth of testing since Azure Cache for Redis is easy to setup and test it. If you don’t see benefits on it you can just delete it. I followed this blog post to configure caching with Redis.
If you have a lot of visitor on the site I think you should definetly evaluate Redis.
Cache Plugins for WordPress
I tested different cache plugins that work with WordPress Multisite and I settled with WP Super Cache. This plugin is simple and quick to configure. If you install the plugin and just enable it it works. Only custom setting I added was in the advanced section I extended cache recycling to 1 hour.
It is possible to get decent performance on WordPress solutions on App Service but I am still in doubt if this is the better solution than running on Virtual Machine or in the container. I never was able to get close to performance that I can get on Virtual Machine with dedicated application server and MySQL server under Linux. Although, Azure is getting better and faster everyday and there is no doubt that eventually it will be at least as fast as VM.
The Az PowerShell module has been for a while the recommended PowerShell module for interacting with Azure. Here is the quick guide how to install AZ on Windows 10.
Powershell script to un-install Azure/AzureRM and install AZ
# Remove base modules:
uninstall-module Azure
uninstall-module AzureRM
# Remove the rest
$Modules = Get-Module -ListAvailable | Where {$_.Name -like 'AzureRM.*'}
Foreach ($Module in $Modules) {Uninstall-Module $Module}
# Install AZ
if ($PSVersionTable.PSEdition -eq 'Desktop' -and (Get-Module -Name AzureRM -ListAvailable)) {
Write-Warning -Message ('Az module not installed. Having both the AzureRM and ' +
'Az modules installed at the same time is not supported.')
} else {
Install-Module -Name Az -AllowClobber -Scope AllUsers -Force
}
# Connect to Azure with a browser sign in token
Connect-AzAccount