Happy to collect different kind of metrics, perhaps more controlled on non-prod hours with single users and actions to correlate.
If you could provide some guidance as to what can be meaninful to the team I’m happy to accomodate if it’s within our grasp.
The *_diff_in_min are negative, if a ticket has breached it’s SLA.
While this can be set in the rails console, the UI option is not ideal right of now.
]]>I’m trying to better understand how SLA behavior is intended to work in Zammad, and whether there is a recommended way to handle this specific scenario.
Here’s the situation:
We have an SLA configured (for example, a 5-minute solution time). When a ticket is created, the SLA starts counting as expected. If the ticket is not resolved within that time, it correctly becomes overdue (shown in red), indicating an SLA breach.
However, when the ticket is eventually resolved and moved to a closed state, the SLA indicator no longer shows the violation — it appears as “normal” (green or neutral), as if the SLA had not been breached.
From an operational and reporting perspective, this is confusing. What we would expect is:
So the main questions are:
I’ve noticed that SLA conditions depend on ticket attributes (like state or category), and that changing these can remove/reapply the SLA. So I’m also wondering if this contributes to the behavior.
Any guidance or best practices would be greatly appreciated.
Thanks in advance!
*
I think we should maybe check in which situations the session is updated, maybe this could be an first step of improvement, before going deeper in the bigger picture of having a alternative session management.
]]>I can see the ticket has been created in less than a second (looking at the logs, and can see the ticket as an Agent). Expect the customer to go from creating the ticket, straight to seeing the newly created ticket.
I timed a 37 second delay between the creation button being clicked and the ticket finally appearing to the customer. During this time, Zammad’s interface was unresponsive.
Reloading the page at any point allowed the customer to carry on normally.
Pressing F12 and viewing the “Network” traffic, showed “message_receive” in a pending state.
Create a ticket as a customer. Creating a ticket as an Agent on behalf of the customer does not replicate the issue.
]]>We would like to share an anonymized production finding and ask you to evaluate whether session handling can be improved for write-heavy environments.
In one of our production systems, PostgreSQL session writes dominate SQL time. The main statement in pg_stat_statements is:
UPDATE "sessions" SET "data" = $1, "updated_at" = $2 WHERE "sessions"."id" = $3
In our workload, this statement accounts for roughly 75% of total SQL execution time. That makes it the clearest database hotspot we found.
Anonymized evidence
UPDATE sessions ...
483,718 calls98.66M ms total execution time203.96 ms mean execution time73.55% of total SQL time in the sample windowOther expensive patterns exist too, mainly around ticket lists, tags, and taskbars, but session writes are the dominant cost.
We also validated that this is not a missing-index problem:
Why we are raising this
Zammad is a Rails application, and Rails supports multiple session storage strategies. For high-concurrency or UI-heavy deployments, PostgreSQL-backed sessions may create unnecessary write amplification.
Because of that, we would like you to evaluate one of these directions:
Why we think this matters
What we would like you to review
Related community threads
We looked for prior reports before posting and found adjacent discussions, but not an exact match for this write-amplification pattern:
These threads suggest sessions are already a known operational topic, but we did not find a prior discussion that specifically addresses sessions writes dominating SQL time in a busy production workload.
Acceptance criteria
UPDATE sessions statements in normal usage.Additional note
We are happy to share more anonymized details if helpful, including:
pg_stat_statements output,EXPLAIN ANALYZE for the main query patterns,Thank you for considering this.
]]>However, there is no ETA for this yet, as it will only be implemented in the next tech stack. Please be patient. I hope this change will also solve your use case.
]]>Since we are at this topic already:
How about the possibility to turn aroud the last opened ticket bar on the left side, so the most recent opened ticket is at the top (:
You might want to consider to keep feature requests clean. ‚Same‘ functionality, but different topic technically.
]]>edit:
Since we are at this topic already:
How about the possibility to turn aroud the last opened ticket bar on the left side, so the most recent opened ticket is at the top (:
About the context window, when this length is also the value which is configured for the Ollama setup (or any other setup), then the window should be fine, it needs to be a very very very long ticket to reach this.
I can maybe check during the week, if this links are some general problems.
Maybe the LLM size can be a problem related to the JSON return structure, difficult to say.
to and cc should be strings IMO. Model
architecture gemma3
parameters 4.3B
context length 131072
embedding length 2560
quantization Q4_0
What size of context window do you suggest?
Alsow what happens to userers that configured a Systemprompt for the Zamamd AI?
We for instance have configured the assistant (our own) in a way that he “knows” what hardware we use, what naming convention our systems use, what software we use generally etc… this way the response is much better tailored to our company requirements.
Best regards
]]>When I change an LDAP setting (e.g., adding a new line to the role assignment), it is neither applied nor saved.
A new LDAP integration completely discards the specified role assignment.
Even a change to the cn in an existing role assignment is completely ignored.
No errors are visible in the log.
What could be the cause?
The changes to the settings should be applied.
Change the setting or create a new LDAP integration.
]]>During setup, I entered a temporary token in the Access Token field and completed the setup. After that, everything worked fine with WhatsApp in Zammad.
Then I replaced the temporary token with the permanent one, and now everything is working as it should.
]]>I dont care about the exact when i choose to show the relative dates. (You still can hover over it, to show the timestamp).
]]>Comment out all the styles in here:
zammad-zammad-scheduler-1:/opt/zammad/app/views/mailer/application_wrapper.html.erb
Example:
<!DOCTYPE html>
<html dir="auto">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<style type="text/css">
body {
###html_email_css_font###
}
/* img {
outline: none;
text-decoration: none;
-ms-interpolation-mode: bicubic;
} */
]]>Hello everyone,
This guide summarizes our field‑tested approach to improving Zammad performance. It is not a universal recipe. The objective is simple: measure first, identify the real bottleneck, and apply targeted changes—one at a time. It turned our laggy patience-tester Zammad instance into a snappy fast user experience.
Before tuning, understand where time is spent:
production.log request timings)If the system is mostly idle but the UI feels slow, the root cause is usually request fan‑out or inefficient request patterns—not lack of hardware.
Reference:
All‑in‑one deployments are common, but every component shares the same resources:
CPU is shared across web workers, background jobs, PostgreSQL, and Elasticsearch. Increasing one layer directly impacts the others.
Reference:
Ensure connection capacity is correctly sized:
rake zammad:db:max_connections
Recommended starting ranges:
shared_buffers: 20–25% of RAMeffective_cache_size: 50–75% of RAMwork_mem: 8–32 MBmaintenance_work_mem: 256 MB–1 GBcheckpoint_timeout: 10–15 minmax_wal_size: 2–8 GBcheckpoint_completion_target: ~0.9random_page_cost: 1.1–1.5 (SSD)Example baseline:
shared_buffers = 4GB
effective_cache_size = 16GB
maintenance_work_mem = 256MB
checkpoint_timeout = 15min
checkpoint_completion_target = 0.9
max_wal_size = 4GB
random_page_cost = 1.1
effective_io_concurrency = 200
work_mem = 20MB
track_io_timing = on
Use pg_stat_statements to identify high‑frequency queries and real hotspots.
A single UI action can trigger dozens or hundreds of queries (tickets, articles, permissions, tags).
Focus on:
This pattern often explains why the database appears fast while the UI feels slow.
Reference:
Baseline configuration:
upstream zammad_backend {
server 127.0.0.1:3000;
keepalive 32;
}
server {
listen 443 ssl http2;
gzip on;
gzip_types text/plain text/css application/json application/javascript;
location /assets/ {
expires 7d;
add_header Cache-Control "public, immutable";
access_log off;
}
location / {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_read_timeout 300;
proxy_pass http://zammad_backend;
}
}
Key considerations:
/assets/ conservatively (7–30 days) for fingerprinted filesReference:
Memcached can reduce repeated computation in read‑heavy or multi‑node environments.
Installation:
apt install memcached
systemctl enable --now memcached
Basic setup (~256–512 MB):
zammad config:set MEMCACHE_SERVERS=127.0.0.1:11211
Its effectiveness depends on cache hit rate. It does not help in highly dynamic workloads.
Reference:
Check cluster status:
curl localhost:9200/_cluster/health?pretty
Guidelines:
-Xms = -Xmx)Monitor:
Elasticsearch competes heavily for both CPU and RAM. Oversizing it can degrade overall system performance.
Reference:
redis-cli info
Ensure:
Reference:
Tune these together, not independently:
ZAMMAD_WEB_CONCURRENCYZAMMAD_PROCESS_DELAYED_JOBS_WORKERSZAMMAD_PROCESS_DELAYED_JOBS_WORKER_THREADSZAMMAD_PROCESS_SESSION_JOBS_WORKERSGuidelines:
Always change one variable at a time.
Zammad performance is inherently multi‑layered:
Measure first. Then optimize the layer that is actually doing the work.
Happy to compare approaches or discuss specific cases.
]]>Our signature added by Exclaimer in daily mail traffic looks like this:
If we send an email from Zammad, the result is this:
It appears Zammad’s stylesheets are conflicting with Exclaimer stylesheets. Is this a known issue? Can it be solved, or does a workaround exist? Note Exclaimer adds the signature after Zammad sent it via Exchange mail rule.
]]>Maybe the docker based installations are more sensitive.
I am indeed using a docker compose-based installation here. And I’ve only had this problem in my environment since upgrading to version 7. Perhaps that will help with the analysis.
rails r ‘p Channel.where(active: true).where.not(area: “Email::Notification”).where(“updated_at < ?”, Time.now - 10.minutes).count’
@MrGeneration Thanks, that should be work. The compose version is, by the way:
docker compose exec zammad-railsserver bundle exec rails r 'p Channel.where(active: true).where.not(area: "Email::Notification").where("updated_at < ?", Time.now - 10.minutes).count'
Perhaps this will help someone here in the community.
The current plan is also that we have the backport available in general in stable. So you can keep in eye on it during the week.
@dominikklein
Very good news! Thanks a lot!
Best regards!
]]>I’d argue at least that the following two workflows should not have different outcomes in the history:
Thanks for raising this question.
We recommend following GitHub Security Advisories Security Advisories · zammad/zammad · GitHub. This is our main channel for publishing security advisories and fixes, and you can subscribe to receive notifications.
For broader updates on Zammad (like major and minor releases, feature news, or events), our newsletters, forum posts in the announcement section, and social media (Mastodon, X, LinkedIn, FB) are helpful additional sources.
Best,
Julia
I’ve created it as:
article_payload = {
"ticket_id": ticket_id,
"subject": article_subject,
"body": article_body,
"to": ["[email protected]"],
"cc": ["[email protected]"],
"type": "phone", # or 'email' depending on use
"internal": False
}
it looks a bit strange but works fine ![]()
Your To/Cc fields in the UI look strange, like an array. Are you sure that this is correct?
I did a bit of testing:
CC works but does not populate the cc in the “reply”
TO works fine
I think this is fine ![]()
I’ll request suppressing the automatic sending of emails when articles are created as a new feature.
Thank you very much for the help ![]()
Cheers
Lukas
as described in Create Email-Article via API we have the following challenge:
We’d like to:
both without this triggering the email to be send out.
Note: We’re not talking notifications but the emails being created as an article.
We’d like to do this because:
“Telephone” works as a workaround but does not support populating the cc-field when using “reply”.
To test the behavior, create a ticket with an email-type article via the API
{
"title": "Ticket with email",
"group": "People working on emails",
"customer": "[email protected]",
"article": {
"subject": "Email subject",
"body": "Email body",
"type": "email",
"from": "[email protected]",
"to": "[email protected]",
"content_type": "text/html",
"internal": false
}
}
This will trigger an email to be send to [email protected].
It would be very nice to have the option su suppress the sending of this email via the API (article and ticket) e.g. by an “outgoing” flag on the article payload. This can be made optional and set to “true” by default to maintain backwards compatibility
{
"title": "Ticket with email",
"group": "People working on emails",
"customer": "[email protected]",
"article": {
"subject": "Email subject",
"body": "Email body",
"type": "email",
"from": "[email protected]",
"to": "[email protected]",
"content_type": "text/html",
"internal": false
}
}
would still trigger the current behavior but
{
"title": "Ticket with email",
"group": "People working on emails",
"customer": "[email protected]",
"article": {
"subject": "Email subject",
"body": "Email body",
"type": "email",
"from": "[email protected]",
"to": "[email protected]",
"content_type": "text/html",
"internal": false,
"outgoing": false
}
}
would not.
As there is a workaround this is somewhat of a “nice-to-have” but it would make handling incoming emails much less hacky ![]()
Cheers
Lukas
Our Zammad environment:
I would like to raise a topic that became very relevant for us last week: security advisories and timely information about security‑relevant updates in Zammad.
I had a regular update planned for last Tuesday to install my custom made package to enable HVE for ticket notifications. On the same day, our office received a PEC email.
For clarity: A PEC (Posta Elettronica Certificata) is an Italian legally certified email system, comparable to a registered letter with return receipt. It is commonly used by public authorities for formal and security‑relevant communications.
The PEC was sent by CSIRT Italia - Agenzia per la Cybersicurezza Nazionale (ACN)
The message concerned current cybersecurity risks about Zammad 6.5.x which was installed at the time, this of course immediately shifted our priorities.
I had already tested the upgrade to Zammad 7.0 weeks before in a test environment and he production update was planned for summer, not immediately.
What caught my attention afterwards was the following:
I only noticed the relevant forum post about the security advisory by chance on Tuesday morning, a few hours before receiving the PEC, although at that time it had already been published around 6 days earlier.
My questions to the Zammad team and the community:
Which official channels does the Zammad team recommend to stay reliably and promptly informed about critical security advisories and CVEs?
What is considered best practice from your experience to avoid learning about security topics “by chance”?
How do other organizations handle this?
Especially in environments where updates are planned, tested, and bound to change windows, early and reliable security information is crucial.
I would really appreciate recommendations from both the Zammad team and other community members.
Best,
Skip
toaddresses in the articles attribute or even use cc for that. cc is cleaner in my opinion. ]]>This can be set via UI or if you can’t use the UI approach any more, via rails console as well.
See the documentation for more.
However, no matter if you’re using tags or a custom selection field, if an agent has to touch the ticket anyway, the question would be why the correct owner can’t be pre-selected.
Anyway, doesn’t matter, selection field is your best pick (in my opinion).
]]>Hard to tell, it might depend on the environment in general.
@ggruening Yes and no. The monitoring endpoint is your best bet.
While it begins screaming after an hour “only”, there is situations where this delay might be “okay” or reasonable. Even with very busy instances it might be.
You can check on rails level, when the Channel(s) where updated last. Email channels (apart from the notification channels) are always updated when they’re done fetching (no matter if successful or not). You could also query the preferences, but last_updated is easier.
Below works on every installation type. Add zammad run for package and the fitting docker based terms in front of below for maximum profit. You want to execute this against the rails server.
rails r 'p Channel.where(active: true).where.not(area: "Email::Notification").where("updated_at < ?", Time.now - 10.minutes).count'
Fair word of warning:
Check once per minute (that’s by far enough), do not reduce the time limit too much. I wouldn’t suggest less than 5 minutes to reduce false positives. Above will always return 0, unless you have n channels not being updated within 10 minutes.