Repository: VictoriaMetrics/VictoriaMetrics
Pull request #6996 (2024-09-12 17:11:25)

vmselect: ensure default -search.maxConcurrentRequests is non-decreasing
### Describe Your Changes

vmselect determines the default value of `-search.maxConcurrentRequests` multiplying the number of available CPUs by 2 if and only if the number is small (to be precise <= 4). That leads `-search.maxConcurrentRequests` is decreasing at the edge of these two cases as shown below:
| CPUs | MaxConcurrentRequests | MaxConcurrentRequests (original proposal) | MaxConcurrentRequests (updated proposal) |
|--------|--------|--------|--------|
| 1 | 2 | 2 | 2 |
| 2 | 4 (prev+2) | 4 (prev+2) | 4 (prev+2) |
| 3 | 6 (prev+2) | 6 (prev+2) | 6 (prev+2) |
| 4 | 8 (prev+2) | 8 (prev+2) | 8 (prev+2) |
| 5 | 5 __(prev-3)__ | 9 __(prev+1)__ | 10 __(prev+2)__ |
| 6 | 6 (prev+1) | 10 (prev+1) | 12 (prev+2) |
| 7 | 7 (prev+1) | 11 (prev+1) | 14 (prev+2) |
| 8 | 8 (prev+1) | 12 (prev+1) | 16 (prev+2) |

I propose to make the default value non-decreasing. 

### Checklist

The following checks are **mandatory**:

- [x] My change adheres [VictoriaMetrics contributing guidelines](https://docs.victoriametrics.com/contributing/).


f41gh7: @fxrlv  could you please squash, sign commit and force push it to PR? Our merge policy requires all commits to be signed.

 See this instruction for details https://docs.github.com/authentication/managing-commit-signature-verification/about-commit-signature-verification

Patch:
diff --git a/app/vlinsert/elasticsearch/elasticsearch.go b/app/vlinsert/elasticsearch/elasticsearch.go
index 280ba007e..fff9f19be 100644
--- a/app/vlinsert/elasticsearch/elasticsearch.go
+++ b/app/vlinsert/elasticsearch/elasticsearch.go
@@ -6,9 +6,7 @@ import (
 	"flag"
 	"fmt"
 	"io"
-	"math"
 	"net/http"
-	"strconv"
 	"strings"
 	"time"
 
@@ -251,19 +249,8 @@ func parseElasticsearchTimestamp(s string) (int64, error) {
 		return 0, nil
 	}
 	if len(s) < len("YYYY-MM-DD") || s[len("YYYY")] != '-' {
-		// Try parsing timestamp in milliseconds
-		n, err := strconv.ParseInt(s, 10, 64)
-		if err != nil {
-			return 0, fmt.Errorf("cannot parse timestamp in milliseconds from %q: %w", s, err)
-		}
-		if n > int64(math.MaxInt64)/1e6 {
-			return 0, fmt.Errorf("too big timestamp in milliseconds: %d; mustn't exceed %d", n, int64(math.MaxInt64)/1e6)
-		}
-		if n < int64(math.MinInt64)/1e6 {
-			return 0, fmt.Errorf("too small timestamp in milliseconds: %d; must be bigger than %d", n, int64(math.MinInt64)/1e6)
-		}
-		n *= 1e6
-		return n, nil
+		// Try parsing timestamp in seconds or milliseconds
+		return insertutils.ParseUnixTimestamp(s)
 	}
 	if len(s) == len("YYYY-MM-DD") {
 		t, err := time.Parse("2006-01-02", s)
diff --git a/app/vlinsert/insertutils/timestamp.go b/app/vlinsert/insertutils/timestamp.go
index e9d41d0a4..978837d09 100644
--- a/app/vlinsert/insertutils/timestamp.go
+++ b/app/vlinsert/insertutils/timestamp.go
@@ -2,6 +2,8 @@ package insertutils
 
 import (
 	"fmt"
+	"math"
+	"strconv"
 	"time"
 
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/logstorage"
@@ -19,15 +21,49 @@ func ExtractTimestampRFC3339NanoFromFields(timeField string, fields []logstorage
 		if f.Name != timeField {
 			continue
 		}
-		if f.Value == "" || f.Value == "0" {
-			return time.Now().UnixNano(), nil
-		}
-		nsecs, ok := logstorage.TryParseTimestampRFC3339Nano(f.Value)
-		if !ok {
-			return 0, fmt.Errorf("cannot unmarshal rfc3339 timestamp from %s=%q", timeField, f.Value)
+		nsecs, err := parseTimestamp(f.Value)
+		if err != nil {
+			return 0, fmt.Errorf("cannot parse timestamp from field %q: %s", timeField, err)
 		}
 		f.Value = ""
+		if nsecs == 0 {
+			nsecs = time.Now().UnixNano()
+		}
 		return nsecs, nil
 	}
 	return time.Now().UnixNano(), nil
 }
+
+func parseTimestamp(s string) (int64, error) {
+	if s == "" || s == "0" {
+		return time.Now().UnixNano(), nil
+	}
+	if len(s) <= len("YYYY") || s[len("YYYY")] != '-' {
+		return ParseUnixTimestamp(s)
+	}
+	nsecs, ok := logstorage.TryParseTimestampRFC3339Nano(s)
+	if !ok {
+		return 0, fmt.Errorf("cannot unmarshal rfc3339 timestamp %q", s)
+	}
+	return nsecs, nil
+}
+
+// ParseUnixTimestamp parses s as unix timestamp in either seconds or milliseconds and returns the parsed timestamp in nanoseconds.
+func ParseUnixTimestamp(s string) (int64, error) {
+	n, err := strconv.ParseInt(s, 10, 64)
+	if err != nil {
+		return 0, fmt.Errorf("cannot parse unix timestamp from %q: %w", s, err)
+	}
+	if n < (1<<31) && n >= (-1<<31) {
+		// The timestamp is in seconds. Convert it to milliseconds
+		n *= 1e3
+	}
+	if n > int64(math.MaxInt64)/1e6 {
+		return 0, fmt.Errorf("too big timestamp in milliseconds: %d; mustn't exceed %d", n, int64(math.MaxInt64)/1e6)
+	}
+	if n < int64(math.MinInt64)/1e6 {
+		return 0, fmt.Errorf("too small timestamp in milliseconds: %d; must be bigger than %d", n, int64(math.MinInt64)/1e6)
+	}
+	n *= 1e6
+	return n, nil
+}
diff --git a/app/vmselect/main.go b/app/vmselect/main.go
index 83fcbdda9..ebbc724ed 100644
--- a/app/vmselect/main.go
+++ b/app/vmselect/main.go
@@ -44,10 +44,7 @@ var (
 var slowQueries = metrics.NewCounter(`vm_slow_queries_total`)
 
 func getDefaultMaxConcurrentRequests() int {
-	n := cgroup.AvailableCPUs()
-	if n <= 4 {
-		n *= 2
-	}
+	n := cgroup.AvailableCPUs() * 2
 	if n > 16 {
 		// A single request can saturate all the CPU cores, so there is no sense
 		// in allowing higher number of concurrent requests - they will just contend
diff --git a/deployment/docker/docker-compose-victorialogs.yml b/deployment/docker/docker-compose-victorialogs.yml
index 200f4cce7..ab276c155 100644
--- a/deployment/docker/docker-compose-victorialogs.yml
+++ b/deployment/docker/docker-compose-victorialogs.yml
@@ -40,7 +40,7 @@ services:
 #  storing logs and serving read queries.
   victorialogs:
     container_name: victorialogs
-    image: docker.io/victoriametrics/victoria-logs:v0.31.0-victorialogs
+    image: docker.io/victoriametrics/victoria-logs:v0.32.0-victorialogs
     command:
       - "--storageDataPath=/vlogs"
       - "--httpListenAddr=:9428"
diff --git a/deployment/docker/victorialogs/compose.yml b/deployment/docker/victorialogs/compose-base.yml
similarity index 94%
rename from deployment/docker/victorialogs/compose.yml
rename to deployment/docker/victorialogs/compose-base.yml
index b67bb1582..33f1026b4 100644
--- a/deployment/docker/victorialogs/compose.yml
+++ b/deployment/docker/victorialogs/compose-base.yml
@@ -1,7 +1,7 @@
 services:
   # meta service will be ignored by compose
   .victorialogs:
-    image: docker.io/victoriametrics/victoria-logs:v0.31.0-victorialogs
+    image: docker.io/victoriametrics/victoria-logs:v0.32.0-victorialogs
     command:
       - -storageDataPath=/vlogs
       - -loggerFormat=json
diff --git a/deployment/docker/victorialogs/filebeat/compose.yml b/deployment/docker/victorialogs/filebeat/compose-base.yml
similarity index 95%
rename from deployment/docker/victorialogs/filebeat/compose.yml
rename to deployment/docker/victorialogs/filebeat/compose-base.yml
index 0b3b38359..4da2cccc0 100644
--- a/deployment/docker/victorialogs/filebeat/compose.yml
+++ b/deployment/docker/victorialogs/filebeat/compose-base.yml
@@ -1,5 +1,5 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 services:
   filebeat:
     image: docker.elastic.co/beats/filebeat:8.15.1
diff --git a/deployment/docker/victorialogs/filebeat/elasticsearch/compose.yml b/deployment/docker/victorialogs/filebeat/elasticsearch/compose.yml
index f15e3b2f5..23e245b02 100644
--- a/deployment/docker/victorialogs/filebeat/elasticsearch/compose.yml
+++ b/deployment/docker/victorialogs/filebeat/elasticsearch/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: filebeat-elasticsearch
diff --git a/deployment/docker/victorialogs/filebeat/syslog/compose.yml b/deployment/docker/victorialogs/filebeat/syslog/compose.yml
index eb908fd0c..5d38d1a17 100644
--- a/deployment/docker/victorialogs/filebeat/syslog/compose.yml
+++ b/deployment/docker/victorialogs/filebeat/syslog/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: filebeat-syslog
diff --git a/deployment/docker/victorialogs/fluentbit/compose.yml b/deployment/docker/victorialogs/fluentbit/compose-base.yml
similarity index 92%
rename from deployment/docker/victorialogs/fluentbit/compose.yml
rename to deployment/docker/victorialogs/fluentbit/compose-base.yml
index 2f38c9f20..c9580679f 100644
--- a/deployment/docker/victorialogs/fluentbit/compose.yml
+++ b/deployment/docker/victorialogs/fluentbit/compose-base.yml
@@ -1,5 +1,5 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 services:
   fluentbit:
     image: cr.fluentbit.io/fluent/fluent-bit:3.1.7
diff --git a/deployment/docker/victorialogs/fluentbit/jsonline-ha/compose.yml b/deployment/docker/victorialogs/fluentbit/jsonline-ha/compose.yml
index ffe557c61..3a9ccc9a9 100644
--- a/deployment/docker/victorialogs/fluentbit/jsonline-ha/compose.yml
+++ b/deployment/docker/victorialogs/fluentbit/jsonline-ha/compose.yml
@@ -1,5 +1,5 @@
 include:
   - path:
-      - ../compose.yml
+      - ../compose-base.yml
       - ../../compose-ha.yml
 name: fluentbit-jsonline-ha
diff --git a/deployment/docker/victorialogs/fluentbit/jsonline/compose.yml b/deployment/docker/victorialogs/fluentbit/jsonline/compose.yml
index 4edd0c18b..fcdecd21b 100644
--- a/deployment/docker/victorialogs/fluentbit/jsonline/compose.yml
+++ b/deployment/docker/victorialogs/fluentbit/jsonline/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: fluentbit-jsonline
diff --git a/deployment/docker/victorialogs/fluentbit/loki/compose.yml b/deployment/docker/victorialogs/fluentbit/loki/compose.yml
index 1627ba043..9cf140127 100644
--- a/deployment/docker/victorialogs/fluentbit/loki/compose.yml
+++ b/deployment/docker/victorialogs/fluentbit/loki/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: fluentbit-loki
diff --git a/deployment/docker/victorialogs/fluentd/compose.yml b/deployment/docker/victorialogs/fluentd/compose-base.yml
similarity index 96%
rename from deployment/docker/victorialogs/fluentd/compose.yml
rename to deployment/docker/victorialogs/fluentd/compose-base.yml
index e189f506e..0d35bfd8e 100644
--- a/deployment/docker/victorialogs/fluentd/compose.yml
+++ b/deployment/docker/victorialogs/fluentd/compose-base.yml
@@ -1,5 +1,5 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 services:
   fluentd:
     build: .
diff --git a/deployment/docker/victorialogs/fluentd/elasticsearch/compose.yml b/deployment/docker/victorialogs/fluentd/elasticsearch/compose.yml
index 9c65b063e..9ec3ada9d 100644
--- a/deployment/docker/victorialogs/fluentd/elasticsearch/compose.yml
+++ b/deployment/docker/victorialogs/fluentd/elasticsearch/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: fluentd-elasticsearch
diff --git a/deployment/docker/victorialogs/fluentd/jsonline/compose.yml b/deployment/docker/victorialogs/fluentd/jsonline/compose.yml
index efe3cb825..f99e29462 100644
--- a/deployment/docker/victorialogs/fluentd/jsonline/compose.yml
+++ b/deployment/docker/victorialogs/fluentd/jsonline/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: fluentd-jsonline
diff --git a/deployment/docker/victorialogs/fluentd/loki/compose.yml b/deployment/docker/victorialogs/fluentd/loki/compose.yml
index 1627ba043..9cf140127 100644
--- a/deployment/docker/victorialogs/fluentd/loki/compose.yml
+++ b/deployment/docker/victorialogs/fluentd/loki/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: fluentbit-loki
diff --git a/deployment/docker/victorialogs/fluentd/syslog/compose.yml b/deployment/docker/victorialogs/fluentd/syslog/compose.yml
index e9e4e82da..d6b2c9656 100644
--- a/deployment/docker/victorialogs/fluentd/syslog/compose.yml
+++ b/deployment/docker/victorialogs/fluentd/syslog/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: fluentbit-syslog
diff --git a/deployment/docker/victorialogs/logstash/compose.yml b/deployment/docker/victorialogs/logstash/compose-base.yml
similarity index 94%
rename from deployment/docker/victorialogs/logstash/compose.yml
rename to deployment/docker/victorialogs/logstash/compose-base.yml
index 4263a392c..8f0ac156d 100644
--- a/deployment/docker/victorialogs/logstash/compose.yml
+++ b/deployment/docker/victorialogs/logstash/compose-base.yml
@@ -1,5 +1,5 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 services:
   logstash:
     build:
diff --git a/deployment/docker/victorialogs/logstash/elasticsearch/compose.yml b/deployment/docker/victorialogs/logstash/elasticsearch/compose.yml
index 79399ecc2..2de18276b 100644
--- a/deployment/docker/victorialogs/logstash/elasticsearch/compose.yml
+++ b/deployment/docker/victorialogs/logstash/elasticsearch/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: logstash-elasticsearch
diff --git a/deployment/docker/victorialogs/logstash/jsonline-ha/compose.yml b/deployment/docker/victorialogs/logstash/jsonline-ha/compose.yml
index d63fa78c0..80a9dae0d 100644
--- a/deployment/docker/victorialogs/logstash/jsonline-ha/compose.yml
+++ b/deployment/docker/victorialogs/logstash/jsonline-ha/compose.yml
@@ -1,5 +1,5 @@
 include:
   - path:
-      - ../compose.yml
+      - ../compose-base.yml
       - ../../compose-ha.yml
 name: logstash-jsonline-ha
diff --git a/deployment/docker/victorialogs/logstash/jsonline/compose.yml b/deployment/docker/victorialogs/logstash/jsonline/compose.yml
index 11d4a0548..b0a1849b1 100644
--- a/deployment/docker/victorialogs/logstash/jsonline/compose.yml
+++ b/deployment/docker/victorialogs/logstash/jsonline/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: logstash-jsonline
diff --git a/deployment/docker/victorialogs/logstash/loki/compose.yml b/deployment/docker/victorialogs/logstash/loki/compose.yml
index 9e3249883..e312b61ac 100644
--- a/deployment/docker/victorialogs/logstash/loki/compose.yml
+++ b/deployment/docker/victorialogs/logstash/loki/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: logstash-loki
diff --git a/deployment/docker/victorialogs/opentelemetry-collector/compose.yml b/deployment/docker/victorialogs/opentelemetry-collector/compose-base.yml
similarity index 94%
rename from deployment/docker/victorialogs/opentelemetry-collector/compose.yml
rename to deployment/docker/victorialogs/opentelemetry-collector/compose-base.yml
index 794f2382b..16e43eef8 100644
--- a/deployment/docker/victorialogs/opentelemetry-collector/compose.yml
+++ b/deployment/docker/victorialogs/opentelemetry-collector/compose-base.yml
@@ -1,5 +1,5 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 services:
   collector:
     image: docker.io/otel/opentelemetry-collector-contrib:0.108.0
diff --git a/deployment/docker/victorialogs/opentelemetry-collector/elasticsearch-ha/compose.yml b/deployment/docker/victorialogs/opentelemetry-collector/elasticsearch-ha/compose.yml
index 6fc7eafd6..e8c3de276 100644
--- a/deployment/docker/victorialogs/opentelemetry-collector/elasticsearch-ha/compose.yml
+++ b/deployment/docker/victorialogs/opentelemetry-collector/elasticsearch-ha/compose.yml
@@ -1,5 +1,5 @@
 include:
  - path:
-     - ../compose.yml
+     - ../compose-base.yml
      - ../../compose-ha.yml
 name: collector-elasticsearch-ha
diff --git a/deployment/docker/victorialogs/opentelemetry-collector/elasticsearch/compose.yml b/deployment/docker/victorialogs/opentelemetry-collector/elasticsearch/compose.yml
index 6d8c4be2d..400e6ef82 100644
--- a/deployment/docker/victorialogs/opentelemetry-collector/elasticsearch/compose.yml
+++ b/deployment/docker/victorialogs/opentelemetry-collector/elasticsearch/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: collector-elasticsearch
diff --git a/deployment/docker/victorialogs/opentelemetry-collector/loki/compose.yml b/deployment/docker/victorialogs/opentelemetry-collector/loki/compose.yml
index 865979e9b..51d822b84 100644
--- a/deployment/docker/victorialogs/opentelemetry-collector/loki/compose.yml
+++ b/deployment/docker/victorialogs/opentelemetry-collector/loki/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: collector-loki
diff --git a/deployment/docker/victorialogs/opentelemetry-collector/otlp/compose.yml b/deployment/docker/victorialogs/opentelemetry-collector/otlp/compose.yml
index 9dcaed9be..2a2fde05e 100644
--- a/deployment/docker/victorialogs/opentelemetry-collector/otlp/compose.yml
+++ b/deployment/docker/victorialogs/opentelemetry-collector/otlp/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: collector-otlp
diff --git a/deployment/docker/victorialogs/opentelemetry-collector/syslog/compose.yml b/deployment/docker/victorialogs/opentelemetry-collector/syslog/compose.yml
index b87ea641e..f5e58d293 100644
--- a/deployment/docker/victorialogs/opentelemetry-collector/syslog/compose.yml
+++ b/deployment/docker/victorialogs/opentelemetry-collector/syslog/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: collector-syslog
diff --git a/deployment/docker/victorialogs/promtail/compose.yml b/deployment/docker/victorialogs/promtail/compose-base.yml
similarity index 93%
rename from deployment/docker/victorialogs/promtail/compose.yml
rename to deployment/docker/victorialogs/promtail/compose-base.yml
index 01d8e01d4..da25f0f1e 100644
--- a/deployment/docker/victorialogs/promtail/compose.yml
+++ b/deployment/docker/victorialogs/promtail/compose-base.yml
@@ -1,5 +1,5 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 services:
   promtail:
     image: grafana/promtail:3.0.1
diff --git a/deployment/docker/victorialogs/promtail/loki/compose.yml b/deployment/docker/victorialogs/promtail/loki/compose.yml
index 5ee00fa08..a229023a9 100644
--- a/deployment/docker/victorialogs/promtail/loki/compose.yml
+++ b/deployment/docker/victorialogs/promtail/loki/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: promtail-elasticsearch
diff --git a/deployment/docker/victorialogs/telegraf/compose.yml b/deployment/docker/victorialogs/telegraf/compose-base.yml
similarity index 95%
rename from deployment/docker/victorialogs/telegraf/compose.yml
rename to deployment/docker/victorialogs/telegraf/compose-base.yml
index 3132712ed..2851c274a 100644
--- a/deployment/docker/victorialogs/telegraf/compose.yml
+++ b/deployment/docker/victorialogs/telegraf/compose-base.yml
@@ -1,5 +1,5 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 services:
   telegraf:
     image: bitnami/telegraf:1.31.3
diff --git a/deployment/docker/victorialogs/telegraf/elasticsearch/compose.yml b/deployment/docker/victorialogs/telegraf/elasticsearch/compose.yml
index e9285fa03..3c9d9d863 100644
--- a/deployment/docker/victorialogs/telegraf/elasticsearch/compose.yml
+++ b/deployment/docker/victorialogs/telegraf/elasticsearch/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: telegraf-elasticsearch
diff --git a/deployment/docker/victorialogs/telegraf/jsonline/compose.yml b/deployment/docker/victorialogs/telegraf/jsonline/compose.yml
index 68d7844a0..bb8bf05cc 100644
--- a/deployment/docker/victorialogs/telegraf/jsonline/compose.yml
+++ b/deployment/docker/victorialogs/telegraf/jsonline/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: telegraf-jsonline
diff --git a/deployment/docker/victorialogs/telegraf/loki/compose.yml b/deployment/docker/victorialogs/telegraf/loki/compose.yml
index 470a80a0a..1f99a2501 100644
--- a/deployment/docker/victorialogs/telegraf/loki/compose.yml
+++ b/deployment/docker/victorialogs/telegraf/loki/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: telegraf-loki
diff --git a/deployment/docker/victorialogs/telegraf/syslog/compose.yml b/deployment/docker/victorialogs/telegraf/syslog/compose.yml
index 698adb2a9..2ee27c969 100644
--- a/deployment/docker/victorialogs/telegraf/syslog/compose.yml
+++ b/deployment/docker/victorialogs/telegraf/syslog/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: telegraf-syslog
diff --git a/deployment/docker/victorialogs/vector/compose.yml b/deployment/docker/victorialogs/vector/compose-base.yml
similarity index 95%
rename from deployment/docker/victorialogs/vector/compose.yml
rename to deployment/docker/victorialogs/vector/compose-base.yml
index 9c9c117d7..bc035bef7 100644
--- a/deployment/docker/victorialogs/vector/compose.yml
+++ b/deployment/docker/victorialogs/vector/compose-base.yml
@@ -1,5 +1,5 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 services:
   vector:
     image: docker.io/timberio/vector:0.40.0-distroless-static
diff --git a/deployment/docker/victorialogs/vector/elasticsearch/compose.yaml b/deployment/docker/victorialogs/vector/elasticsearch/compose.yaml
index bbb51e727..3e284ce3b 100644
--- a/deployment/docker/victorialogs/vector/elasticsearch/compose.yaml
+++ b/deployment/docker/victorialogs/vector/elasticsearch/compose.yaml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: vector-elasticsearch
diff --git a/deployment/docker/victorialogs/vector/jsonline-ha/compose.yml b/deployment/docker/victorialogs/vector/jsonline-ha/compose.yml
index 7d873452b..cb5d3dc41 100644
--- a/deployment/docker/victorialogs/vector/jsonline-ha/compose.yml
+++ b/deployment/docker/victorialogs/vector/jsonline-ha/compose.yml
@@ -1,5 +1,5 @@
 include:
   - path:
-      - ../compose.yml
+      - ../compose-base.yml
       - ../../compose-ha.yml
 name: vector-jsonline-ha
diff --git a/deployment/docker/victorialogs/vector/jsonline/compose.yml b/deployment/docker/victorialogs/vector/jsonline/compose.yml
index 10a44b140..ac6778e4f 100644
--- a/deployment/docker/victorialogs/vector/jsonline/compose.yml
+++ b/deployment/docker/victorialogs/vector/jsonline/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: vector-jsonline
diff --git a/deployment/docker/victorialogs/vector/loki/compose.yml b/deployment/docker/victorialogs/vector/loki/compose.yml
index 433c2bf9a..708e61097 100644
--- a/deployment/docker/victorialogs/vector/loki/compose.yml
+++ b/deployment/docker/victorialogs/vector/loki/compose.yml
@@ -1,3 +1,3 @@
 include:
- - ../compose.yml
+ - ../compose-base.yml
 name: vector-loki
diff --git a/deployment/logs-benchmark/docker-compose.yml b/deployment/logs-benchmark/docker-compose.yml
index 6bc616512..a93ba84cb 100644
--- a/deployment/logs-benchmark/docker-compose.yml
+++ b/deployment/logs-benchmark/docker-compose.yml
@@ -3,7 +3,7 @@ version: '3'
 services:
   # Run `make package-victoria-logs` to build victoria-logs image
   vlogs:
-    image: docker.io/victoriametrics/victoria-logs:v0.31.0-victorialogs
+    image: docker.io/victoriametrics/victoria-logs:v0.32.0-victorialogs
     volumes:
       - vlogs:/vlogs
     ports:
diff --git a/docs/VictoriaLogs/CHANGELOG.md b/docs/VictoriaLogs/CHANGELOG.md
index 197bff6f8..b6516630c 100644
--- a/docs/VictoriaLogs/CHANGELOG.md
+++ b/docs/VictoriaLogs/CHANGELOG.md
@@ -15,6 +15,16 @@ according to [these docs](https://docs.victoriametrics.com/victorialogs/quicksta
 
 ## tip
 
+## [v0.32.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v0.32.0-victorialogs)
+
+Released at 2024-09-29
+
+* FEATURE: [data ingestion](https://docs.victoriametrics.com/victorialogs/data-ingestion/): accept Unix timestamps in seconds in the ingested logs. This simplifies integration with systems, which prefer Unix timestamps over text-based representation of time.
+* FEATURE: [`sort` pipe](https://docs.victoriametrics.com/victorialogs/logsql/#sort-pipe): allow using `order` alias instead of `sort`. For example, `_time:5s | order by (_time)` query works the same as `_time:5s | sort by (_time)`. This simplifies the to [LogsQL](https://docs.victoriametrics.com/victorialogs/logsql/) transition from SQL-like query languages.
+* FEATURE: [`stats` pipe](https://docs.victoriametrics.com/victorialogs/logsql/#stats-pipe): allow using multiple identical [stats functions](https://docs.victoriametrics.com/victorialogs/logsql/#stats-pipe-functions) with distinct [filters](https://docs.victoriametrics.com/victorialogs/logsql/#stats-with-additional-filters) and automatically generated result names. For example, `_time:5m | count(), count() if (error)` query works as expected now, e.g. it returns two results over the last 5 minutes: the total number of logs and the number of logs with `error` [word](https://docs.victoriametrics.com/victorialogs/logsql/#word). Previously this query couldn't be executed because the `if (...)` condition wasn't included in the automatically generate result name, so both results had the same name - `count(*)`.
+
+* BUGFIX: properly calculate [`uniq`](https://docs.victoriametrics.com/victorialogs/logsql/#uniq-pipe) and [`top`](https://docs.victoriametrics.com/victorialogs/logsql/#top-pipe) pipes. Previously they could return invalid results in some cases.
+
 ## [v0.31.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v0.31.0-victorialogs)
 
 Released at 2024-09-27
diff --git a/docs/VictoriaLogs/LogsQL.md b/docs/VictoriaLogs/LogsQL.md
index 2249106bd..7d26a7f52 100644
--- a/docs/VictoriaLogs/LogsQL.md
+++ b/docs/VictoriaLogs/LogsQL.md
@@ -2110,6 +2110,12 @@ The `by` keyword can be skipped in `sort ...` pipe. For example, the following q
 _time:5m | sort (foo, bar) desc
 ```
 
+The `order` alias can be used instead of `sort`, so the following query is equivalent to the previous one:
+
+```logsql
+_time:5m | order by (foo, bar) desc
+```
+
 Sorting of big number of logs can consume a lot of CPU time and memory. Sometimes it is enough to return the first `N` entries with the biggest
 or the smallest values. This can be done by adding `limit N` to the end of `sort ...` pipe.
 Such a query consumes lower amounts of memory when sorting big number of logs, since it keeps in memory only `N` log entries.
diff --git a/docs/VictoriaLogs/QuickStart.md b/docs/VictoriaLogs/QuickStart.md
index 6fc31ad05..a78db8f13 100644
--- a/docs/VictoriaLogs/QuickStart.md
+++ b/docs/VictoriaLogs/QuickStart.md
@@ -33,8 +33,8 @@ Just download archive for the needed Operating system and architecture, unpack i
 For example, the following commands download VictoriaLogs archive for Linux/amd64, unpack and run it:
 
 ```sh
-curl -L -O https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v0.31.0-victorialogs/victoria-logs-linux-amd64-v0.31.0-victorialogs.tar.gz
-tar xzf victoria-logs-linux-amd64-v0.31.0-victorialogs.tar.gz
+curl -L -O https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v0.32.0-victorialogs/victoria-logs-linux-amd64-v0.32.0-victorialogs.tar.gz
+tar xzf victoria-logs-linux-amd64-v0.32.0-victorialogs.tar.gz
 ./victoria-logs-prod
 ```
 
@@ -58,7 +58,7 @@ Here is the command to run VictoriaLogs in a Docker container:
 
 ```sh
 docker run --rm -it -p 9428:9428 -v ./victoria-logs-data:/victoria-logs-data \
-  docker.io/victoriametrics/victoria-logs:v0.31.0-victorialogs
+  docker.io/victoriametrics/victoria-logs:v0.32.0-victorialogs
 ```
 
 See also:
diff --git a/docs/VictoriaLogs/data-ingestion/README.md b/docs/VictoriaLogs/data-ingestion/README.md
index a548a195a..d84cd7603 100644
--- a/docs/VictoriaLogs/data-ingestion/README.md
+++ b/docs/VictoriaLogs/data-ingestion/README.md
@@ -46,9 +46,14 @@ It is possible to push thousands of log lines in a single request to this API.
 
 If the [timestamp field](https://docs.victoriametrics.com/victorialogs/keyconcepts/#time-field) is set to `"0"`,
 then the current timestamp at VictoriaLogs side is used per each ingested log line.
-Otherwise the timestamp field must be in the [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) or [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) format.
-For example, `2023-06-20T15:32:10Z` or `2023-06-20 15:32:10.123456789+02:00`.
-If timezone information is missing (for example, `2023-06-20 15:32:10`), then the time is parsed in the local timezone of the host where VictoriaLogs runs.
+Otherwise the timestamp field must be in one of the following formats:
+
+- [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) or [RFC3339](https://www.rfc-editor.org/rfc/rfc3339).
+  For example, `2023-06-20T15:32:10Z` or `2023-06-20 15:32:10.123456789+02:00`.
+  If timezone information is missing (for example, `2023-06-20 15:32:10`),
+  then the time is parsed in the local timezone of the host where VictoriaLogs runs.
+
+- Unix timestamp in seconds or in milliseconds. For example, `1686026893` (seconds) or `1686026893735` (milliseconds).
 
 See [these docs](https://docs.victoriametrics.com/victorialogs/keyconcepts/#data-model) for details on fields,
 which must be present in the ingested log messages.
@@ -96,9 +101,14 @@ It is possible to push unlimited number of log lines in a single request to this
 
 If the [timestamp field](https://docs.victoriametrics.com/victorialogs/keyconcepts/#time-field) is set to `"0"`,
 then the current timestamp at VictoriaLogs side is used per each ingested log line.
-Otherwise the timestamp field must be in the [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) or [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) format.
-For example, `2023-06-20T15:32:10Z` or `2023-06-20 15:32:10.123456789+02:00`.
-If timezone information is missing (for example, `2023-06-20 15:32:10`), then the time is parsed in the local timezone of the host where VictoriaLogs runs.
+Otherwise the timestamp field must be in one of the following formats:
+
+- [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) or [RFC3339](https://www.rfc-editor.org/rfc/rfc3339).
+  For example, `2023-06-20T15:32:10Z` or `2023-06-20 15:32:10.123456789+02:00`.
+  If timezone information is missing (for example, `2023-06-20 15:32:10`),
+  then the time is parsed in the local timezone of the host where VictoriaLogs runs.
+
+- Unix timestamp in seconds or in milliseconds. For example, `1686026893` (seconds) or `1686026893735` (milliseconds).
 
 See [these docs](https://docs.victoriametrics.com/victorialogs/keyconcepts/#data-model) for details on fields,
 which must be present in the ingested log messages.
diff --git a/docs/VictoriaLogs/keyConcepts.md b/docs/VictoriaLogs/keyConcepts.md
index dd1e5f8d7..d1b38ba65 100644
--- a/docs/VictoriaLogs/keyConcepts.md
+++ b/docs/VictoriaLogs/keyConcepts.md
@@ -135,7 +135,15 @@ during [data ingestion](https://docs.victoriametrics.com/victorialogs/data-inges
 ### Time field
 
 The ingested [log entries](#data-model) may contain `_time` field with the timestamp of the ingested log entry.
-The timestamp must be in [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) or [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) format.
+The timestamp field must be in one of the following formats:
+
+- [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) or [RFC3339](https://www.rfc-editor.org/rfc/rfc3339).
+  For example, `2023-06-20T15:32:10Z` or `2023-06-20 15:32:10.123456789+02:00`.
+  If timezone information is missing (for example, `2023-06-20 15:32:10`),
+  then the time is parsed in the local timezone of the host where VictoriaLogs runs.
+
+- Unix timestamp in seconds or in milliseconds. For example, `1686026893` (seconds) or `1686026893735` (milliseconds).
+
 For example, the following [log entry](#data-model) contains valid timestamp with millisecond precision in the `_time` field:
 
 ```json
@@ -152,7 +160,7 @@ field via `_time_field` query arg during [data ingestion](https://docs.victoriam
 For example, if timestamp is located in the `event.created` field, then specify `_time_field=event.created` query arg
 during [data ingestion](https://docs.victoriametrics.com/victorialogs/data-ingestion/).
 
-If `_time` field is missing, then the data ingestion time is used as log entry timestamp.
+If `_time` field is missing or if it equals `0`, then the data ingestion time is used as log entry timestamp.
 
 The `_time` field is used in [time filter](https://docs.victoriametrics.com/victorialogs/logsql/#time-filter) for quickly narrowing down
 the search to a particular time range.
diff --git a/docs/changelog/CHANGELOG.md b/docs/changelog/CHANGELOG.md
index a47759ea8..c8808af14 100644
--- a/docs/changelog/CHANGELOG.md
+++ b/docs/changelog/CHANGELOG.md
@@ -31,7 +31,8 @@ See also [LTS releases](https://docs.victoriametrics.com/lts-releases/).
 * FEATURE: [dashboards](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/dashboards) for VM single-node, cluster, vmalert, vmagent, VictoriaLogs: add `Go scheduling latency` panel to show the 99th quantile of Go goroutines scheduling. This panel should help identifying insufficient CPU resources for the service. It is especially useful if CPU gets throttled, which now should be visible on this panel.
 * FEATURE: [alerts](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/deployment/docker/alerts-health.yml): add alerting rule to track the Go scheduling latency for goroutines. It should notify users if VM component doesn't have enough CPU to run or gets throttled.
 * FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent/) and [Single-node VictoriaMetrics](https://docs.victoriametrics.com/): hide jobs that contain only healthy targets when `show_only_unhealthy` filter is enabled. Before, jobs without unhealthy targets were still displayed on the page. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3536).
-* FEATURE: [vmalert](https://docs.victoriametrics.com/vmalert): bump default values for sending data to `remoteWrite.url`: `remoteWrite.maxQueueSize` from `100_000` to `1_000_000`, `remoteWrite.maxBatchSize` from `1_000` to `10_000`, `remoteWrite.concurrency` from `1` to `4`. The new settings should improve remote write performance of vmalert with default settings.  
+* FEATURE: [vmalert](https://docs.victoriametrics.com/vmalert): bump default values for sending data to `remoteWrite.url`: `remoteWrite.maxQueueSize` from `100_000` to `1_000_000`, `remoteWrite.maxBatchSize` from `1_000` to `10_000`, `remoteWrite.concurrency` from `1` to `4`. The new settings should improve remote write performance of vmalert with default settings.
+* FEATURE: [vmbackupmanager](https://docs.victoriametrics.com/vmbackupmanager/): add API for creating/scheduling backups. See [documentation](https://docs.victoriametrics.com/vmbackupmanager/#api-methods)
 
 * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent/) fix service discovery of Azure Virtual Machines for response contains `nextLink` in `Host:Port` format. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6912).
 * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent/): properly consume messages [from kafka](https://docs.victoriametrics.com/vmagent/#kafka-integration). Previously vmagent could skip some messages during start-up.
@@ -50,6 +51,7 @@ See also [LTS releases](https://docs.victoriametrics.com/lts-releases/).
 * BUGFIX: [MetricsQL](https://docs.victoriametrics.com/metricsql/): consistently return the first non-`NaN` value from [`range_first`](https://docs.victoriametrics.com/metricsql/#range_first) function across all the returned data points. Previously `NaN` data points weren't replaced with the first non-`NaN` value.
 * BUGFIX: [MetricsQL](https://docs.victoriametrics.com/metricsql/): consistently return the last non-`NaN` value from [`range_last`](https://docs.victoriametrics.com/metricsql/#range_last) function across all the returned data points. Previously `NaN` data points weren't replaced with the last non-`NaN` value.
 * BUGFIX: all VictoriaMetrics components: increase default value of `-loggerMaxArgLen` cmd-line flag from 1000 to 5000. This should improve visibility on errors produced by very long queries.
+* BUGFIX: all VictoriaMetrics components: trim trailing spaces when reading content from `*.passwordFile` and similar flags. It reverts changes introduced at [v1.102.0-rc2](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.102.0-rc2) release. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6986) for details.
 
 ## [v1.103.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.103.0)
 
diff --git a/docs/helm/victoria-metrics-agent/CHANGELOG.md b/docs/helm/victoria-metrics-agent/CHANGELOG.md
index 4eaa638a3..f5670ce57 100644
--- a/docs/helm/victoria-metrics-agent/CHANGELOG.md
+++ b/docs/helm/victoria-metrics-agent/CHANGELOG.md
@@ -1,6 +1,18 @@
 ## Next release
 
+- TODO
+
+## 0.13.0
+
+**Release date:** 2024-09-27
+
+![AppVersion: v1.103.0](https://img.shields.io/static/v1?label=AppVersion&message=v1.103.0&color=success&logo=)
+![Helm: v3](https://img.shields.io/static/v1?label=Helm&message=v3&color=informational&logo=helm)
+
+**Update note**: `remoteWriteUrls` and `multiTenantUrls` parameters were replaced by `remoteWrite`. Please follow [upgrade guide](./README.md#upgrade-to-0130)
+
 - Fail if no remoteWriteUrls set
+- Added `remoteWrite` array param, which can contain all `remoteWrite.*` flag values. Please check chart docs for details.
 
 ## 0.12.2
 
diff --git a/docs/helm/victoria-metrics-agent/README.md b/docs/helm/victoria-metrics-agent/README.md
index 3d71e22f1..a8016a64b 100644
--- a/docs/helm/victoria-metrics-agent/README.md
+++ b/docs/helm/victoria-metrics-agent/README.md
@@ -1,4 +1,4 @@
-![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![Version: 0.12.2](https://img.shields.io/badge/Version-0.12.2-informational?style=flat-square)
+![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![Version: 0.13.0](https://img.shields.io/badge/Version-0.13.0-informational?style=flat-square)
 [![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/victoriametrics)](https://artifacthub.io/packages/helm/victoriametrics/victoria-metrics-agent)
 [![Slack](https://img.shields.io/badge/join%20slack-%23victoriametrics-brightgreen.svg)](https://slack.victoriametrics.com/)
 
@@ -90,6 +90,28 @@ See the history of versions of `vma` application with command.
 helm history vma -n NAMESPACE
 ```
 
+## Upgrade guide
+
+### Upgrade to 0.13.0
+
+- replace `remoteWriteUrls` to `remoteWrite`:
+
+Given below config
+
+```yaml
+remoteWriteUrls:
+- http://address1/api/v1/write
+- http://address2/api/v1/write
+```
+
+should be changed to
+
+```yaml
+remoteWrite:
+- url: http://address1/api/v1/write
+- url: http://address2/api/v1/write
+```
+
 ## How to uninstall
 
 Remove application with command.
@@ -882,17 +904,6 @@ name: ""
 </pre>
 </td>
       <td><p>Existing secret name</p>
-</td>
-    </tr>
-    <tr>
-      <td>multiTenantUrls</td>
-      <td>list</td>
-      <td><pre class="helm-vars-default-value" language-yaml" lang="plaintext">
-<code class="language-yaml">[]
-</code>
-</pre>
-</td>
-      <td><p>Destination multitenant endpoint for scraped/received metrics</p>
 </td>
     </tr>
     <tr>
@@ -1144,14 +1155,14 @@ periodSeconds: 15
 </td>
     </tr>
     <tr>
-      <td>remoteWriteUrls</td>
-      <td>list</td>
-      <td><pre class="helm-vars-default-value" language-yaml" lang="plaintext">
-<code class="language-yaml">[]
+      <td>remoteWrite</td>
+      <td>string</td>
+      <td><pre class="helm-vars-default-value" language-yaml" lang="">
+<code class="language-yaml">null
 </code>
 </pre>
 </td>
-      <td><p>WARN: need to specify at least one remote write url or one multi tenant url</p>
+      <td><p>Generates <code>remoteWrite.*</code> flags and config maps with value content for values, that are of type list of map. Each item should contain <code>url</code> param to pass validation.</p>
 </td>
     </tr>
     <tr>
diff --git a/docs/helm/victoria-metrics-k8s-stack/CHANGELOG.md b/docs/helm/victoria-metrics-k8s-stack/CHANGELOG.md
index d044b526a..5e85c6f66 100644
--- a/docs/helm/victoria-metrics-k8s-stack/CHANGELOG.md
+++ b/docs/helm/victoria-metrics-k8s-stack/CHANGELOG.md
@@ -2,6 +2,15 @@
 
 - TODO
 
+## 0.26.0
+
+**Release date:** 2024-09-29
+
+![AppVersion: v1.102.1](https://img.shields.io/static/v1?label=AppVersion&message=v1.102.1&color=success&logo=)
+![Helm: v3](https://img.shields.io/static/v1?label=Helm&message=v3&color=informational&logo=helm)
+
+- updates operator to [v0.48.3](https://github.com/VictoriaMetrics/operator/releases/tag/v0.48.3)
+
 ## 0.25.17
 
 **Release date:** 2024-09-20
diff --git a/docs/helm/victoria-metrics-k8s-stack/README.md b/docs/helm/victoria-metrics-k8s-stack/README.md
index a501c5670..452f76dbe 100644
--- a/docs/helm/victoria-metrics-k8s-stack/README.md
+++ b/docs/helm/victoria-metrics-k8s-stack/README.md
@@ -1,4 +1,4 @@
-![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![Version: 0.25.17](https://img.shields.io/badge/Version-0.25.17-informational?style=flat-square)
+![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![Version: 0.26.0](https://img.shields.io/badge/Version-0.26.0-informational?style=flat-square)
 [![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/victoriametrics)](https://artifacthub.io/packages/helm/victoriametrics/victoria-metrics-k8s-stack)
 
 Kubernetes monitoring on VictoriaMetrics stack. Includes VictoriaMetrics Operator, Grafana dashboards, ServiceScrapes and VMRules
diff --git a/docs/helm/victoria-metrics-operator/CHANGELOG.md b/docs/helm/victoria-metrics-operator/CHANGELOG.md
index 36b8f2d24..30cd69b7e 100644
--- a/docs/helm/victoria-metrics-operator/CHANGELOG.md
+++ b/docs/helm/victoria-metrics-operator/CHANGELOG.md
@@ -2,6 +2,15 @@
 
 - TODO
 
+## 0.35.2
+
+**Release date:** 2024-09-29
+
+![AppVersion: v0.48.3](https://img.shields.io/static/v1?label=AppVersion&message=v0.48.3&color=success&logo=)
+![Helm: v3](https://img.shields.io/static/v1?label=Helm&message=v3&color=informational&logo=helm)
+
+- updates operator to [v0.48.3](https://github.com/VictoriaMetrics/operator/releases/tag/v0.48.3) version
+
 ## 0.35.1
 
 **Release date:** 2024-09-26
diff --git a/docs/helm/victoria-metrics-operator/README.md b/docs/helm/victoria-metrics-operator/README.md
index 665417602..5a2bdc9ed 100644
--- a/docs/helm/victoria-metrics-operator/README.md
+++ b/docs/helm/victoria-metrics-operator/README.md
@@ -1,4 +1,4 @@
-![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![Version: 0.35.1](https://img.shields.io/badge/Version-0.35.1-informational?style=flat-square)
+![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![Version: 0.35.2](https://img.shields.io/badge/Version-0.35.2-informational?style=flat-square)
 [![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/victoriametrics)](https://artifacthub.io/packages/helm/victoriametrics/victoria-metrics-operator)
 
 Victoria Metrics Operator
diff --git a/docs/operator/CHANGELOG.md b/docs/operator/CHANGELOG.md
index 88a4fa1fe..559fcf785 100644
--- a/docs/operator/CHANGELOG.md
+++ b/docs/operator/CHANGELOG.md
@@ -11,6 +11,12 @@ aliases:
   - /operator/changelog/index.html
 ---
 
+## [v0.48.3](https://github.com/VictoriaMetrics/operator/releases/tag/v0.48.3) - 29 Sep 2024
+
+- [vmcluster](https://docs.victoriametrics.com/operator/resources/vmcluster): properly apply global container registry from configuration. It was ignored for `VMCluster` since `v0.48.0` release. See [this issue](https://github.com/VictoriaMetrics/operator/issues/1118) for details.
+- [operator](https://docs.victoriametrics.com/operator/): updates default vlogs app version to v0.32.0
+- [operator](https://docs.victoriametrics.com/operator/): adds new flag `--disableControllerForCRD`. It allows to disable reconcile controller for the given comma-separated list of CRD names. See [this issue](https://github.com/VictoriaMetrics/operator/issues/528) for details.
+
 ## [v0.48.2](https://github.com/VictoriaMetrics/operator/releases/tag/v0.48.2) - 27 Sep 2024
 
 - [operator](https://docs.victoriametrics.com/operator/): properly expose `vm_app_version` metric tag with `version` and `short_version` build info. It was broken since v0.46.0 release.
diff --git a/docs/operator/vars.md b/docs/operator/vars.md
index 9cf6278c2..d5d74dbde 100644
--- a/docs/operator/vars.md
+++ b/docs/operator/vars.md
@@ -10,7 +10,7 @@ aliases:
   - /operator/vars/index.html
 ---
 <!-- this doc autogenerated - don't edit it manually -->
- updated at Fri Sep 27 13:40:34 UTC 2024
+ updated at Sun Sep 29 19:33:17 UTC 2024
 
 
 | variable name | variable default value | variable required | variable description |
@@ -20,7 +20,7 @@ aliases:
 | VM_CUSTOMCONFIGRELOADERIMAGE | victoriametrics/operator:config-reloader-v0.48.2 | false | - |
 | VM_PSPAUTOCREATEENABLED | false | false | - |
 | VM_VLOGSDEFAULT_IMAGE | victoriametrics/victoria-logs | false | - |
-| VM_VLOGSDEFAULT_VERSION | v0.31.0-victorialogs | false | - |
+| VM_VLOGSDEFAULT_VERSION | v0.32.0-victorialogs | false | - |
 | VM_VLOGSDEFAULT_CONFIGRELOADIMAGE | - | false | ignored |
 | VM_VLOGSDEFAULT_PORT | 9428 | false | - |
 | VM_VLOGSDEFAULT_USEDEFAULTRESOURCES | true | false | - |
@@ -136,4 +136,4 @@ aliases:
 | VM_PODWAITREADYINTERVALCHECK | 5s | false | Defines poll interval for pods ready check at statefulset rollout update |
 | VM_FORCERESYNCINTERVAL | 60s | false | configures force resync interval for VMAgent, VMAlert, VMAlertmanager and VMAuth. |
 | VM_ENABLESTRICTSECURITY | false | false | EnableStrictSecurity will add default `securityContext` to pods and containers created by operator Default PodSecurityContext include: 1. RunAsNonRoot: true 2. RunAsUser/RunAsGroup/FSGroup: 65534 '65534' refers to 'nobody' in all the used default images like alpine, busybox. If you're using customize image, please make sure '65534' is a valid uid in there or specify SecurityContext. 3. FSGroupChangePolicy: &onRootMismatch If KubeVersion>=1.20, use `FSGroupChangePolicy="onRootMismatch"` to skip the recursive permission change when the root of the volume already has the correct permissions 4. SeccompProfile:      type: RuntimeDefault Use `RuntimeDefault` seccomp profile by default, which is defined by the container runtime, instead of using the Unconfined (seccomp disabled) mode. Default container SecurityContext include: 1. AllowPrivilegeEscalation: false 2. ReadOnlyRootFilesystem: true 3. Capabilities:      drop:        - all turn off `EnableStrictSecurity` by default, see https://github.com/VictoriaMetrics/operator/issues/749 for details |
-[envconfig-sum]: 97c30e81298d2e6bde28647c913b9b88
\ No newline at end of file
+[envconfig-sum]: bcf2b739473583d36da69a3c4c3835cf
\ No newline at end of file
diff --git a/docs/vmagent.md b/docs/vmagent.md
index 4f5d2e900..72e71f131 100644
--- a/docs/vmagent.md
+++ b/docs/vmagent.md
@@ -267,16 +267,17 @@ There is also support for multitenant writes. See [these docs](#multitenancy).
 for the collected samples. Examples:
 
 - The following command instructs `vmagent` to send only the last sample per each seen [time series](https://docs.victoriametrics.com/keyconcepts/#time-series) per every 60 seconds:
-  ```
-  ./vmagent -remoteWrite.url=http://remote-storage/api/v1/write -remoteWrite.streamAggr.dedupInterval=60s
+  ```sh
+  ./vmagent -remoteWrite.url=http://remote-storage/api/v1/write -streamAggr.dedupInterval=60s
   ```
 
 - The following command instructs `vmagent` to merge [time series](https://docs.victoriametrics.com/keyconcepts/#time-series) with different `replica` label values
-  and then to send only the last sample per each merged series per ever 60 seconds:
-  ```
-  ./vmagent -remoteWrite=http://remote-storage/api/v1/write -streamAggr.dropInputLabels=replica -remoteWrite.streamAggr.dedupInterval=60s
+  and then to send only the last sample per each merged series per every 60 seconds:
+  ```sh
+  ./vmagent -remoteWrite=http://remote-storage/api/v1/write -streamAggr.dropInputLabels=replica -streamAggr.dedupInterval=60s
   ```
 
+
 ## SRV urls
 
 If `vmagent` encounters urls with `srv+` prefix in hostname (such as `http://srv+some-addr/some/path`), then it resolves `some-addr` [DNS SRV](https://en.wikipedia.org/wiki/SRV_record)
diff --git a/docs/vmbackupmanager.md b/docs/vmbackupmanager.md
index f2f0a69d6..1e24fe1b5 100644
--- a/docs/vmbackupmanager.md
+++ b/docs/vmbackupmanager.md
@@ -202,19 +202,25 @@ For example:
 
 `vmbackupmanager` exposes the following API methods:
 
-* GET `/api/v1/backups` - returns list of backups in remote storage.
-  Example output:
+* POST `/api/v1/backups` - schedule/create the backup. Response examples:
+
+  success, status code - 201, body:
   ```json
-  [{"name":"daily/2023-04-07","size_bytes":318837,"size":"311.4ki","created_at":"2023-04-07T16:15:07+00:00"},{"name":"hourly/2023-04-07:11","size_bytes":318837,"size":"311.4ki","created_at":"2023-04-07T16:15:06+00:00"},{"name":"latest","size_bytes":318837,"size":"311.4ki","created_at":"2023-04-07T16:15:04+00:00"},{"name":"monthly/2023-04","size_bytes":318837,"size":"311.4ki","created_at":"2023-04-07T16:15:10+00:00"},{"name":"weekly/2023-14","size_bytes":318837,"size":"311.4ki","created_at":"2023-04-07T16:15:09+00:00"}]
+      {}
   ```
-  > Note: `created_at` field is in RFC3339 format.
 
-* GET `/api/v1/backups/<BACKUP_NAME>` - returns backup info by name.
-  Example output:
+  failure, status code - 400, body:
   ```json
-  {"name":"daily/2023-04-07","size_bytes":318837,"size":"311.4ki","created_at":"2023-04-07T16:15:07+00:00","locked":true}
+      {"error": "backups <name> is in progress"}
   ```
 
+* GET `/api/v1/backups` - returns list of backups in remote storage.
+  Response example:
+  ```json
+  [{"name":"daily/2023-04-07","size_bytes":318837,"size":"311.4ki","created_at":"2023-04-07T16:15:07+00:00"},{"name":"hourly/2023-04-07:11","size_bytes":318837,"size":"311.4ki","created_at":"2023-04-07T16:15:06+00:00"},{"name":"latest","size_bytes":318837,"size":"311.4ki","created_at":"2023-04-07T16:15:04+00:00"},{"name":"monthly/2023-04","size_bytes":318837,"size":"311.4ki","created_at":"2023-04-07T16:15:10+00:00"},{"name":"weekly/2023-14","size_bytes":318837,"size":"311.4ki","created_at":"2023-04-07T16:15:09+00:00"}]
+  ```
+  > Note: `created_at` field is in RFC3339 format.
+  
 * PUT `/api/v1/backups/<BACKUP_NAME>` - update "locked" attribute for backup by name.
   Example request body:
   ```json
diff --git a/lib/fs/fscore/fscore.go b/lib/fs/fscore/fscore.go
index 03cc37562..b67028203 100644
--- a/lib/fs/fscore/fscore.go
+++ b/lib/fs/fscore/fscore.go
@@ -7,6 +7,8 @@ import (
 	"net/url"
 	"os"
 	"path/filepath"
+	"strings"
+	"unicode"
 )
 
 // ReadPasswordFromFileOrHTTP reads password for the give path.
@@ -17,7 +19,8 @@ func ReadPasswordFromFileOrHTTP(path string) (string, error) {
 	if err != nil {
 		return "", err
 	}
-	return string(data), nil
+	pass := strings.TrimRightFunc(string(data), unicode.IsSpace)
+	return pass, nil
 }
 
 // ReadFileOrHTTP reads path either from local filesystem or from http if path starts with http or https.
diff --git a/lib/logstorage/parser.go b/lib/logstorage/parser.go
index 2ec250030..d4970c6d2 100644
--- a/lib/logstorage/parser.go
+++ b/lib/logstorage/parser.go
@@ -840,7 +840,7 @@ func parseGenericFilter(lex *lexer, fieldName string) (filter, error) {
 		}
 		return f, nil
 	case lex.isKeyword("("):
-		if !lex.isSkippedSpace && !lex.isPrevToken("", ":", "(", "!", "not") {
+		if !lex.isSkippedSpace && !lex.isPrevToken("", ":", "(", "!", "-", "not") {
 			return nil, fmt.Errorf("missing whitespace before the search word %q", lex.prevToken)
 		}
 		return parseParensFilter(lex, fieldName)
@@ -889,7 +889,7 @@ func parseGenericFilter(lex *lexer, fieldName string) (filter, error) {
 }
 
 func getCompoundPhrase(lex *lexer, allowColon bool) (string, error) {
-	stopTokens := []string{"*", ",", "(", ")", "[", "]", "|", "!", ""}
+	stopTokens := []string{"*", ",", "(", ")", "[", "]", "|", ""}
 	if lex.isKeyword(stopTokens...) {
 		return "", fmt.Errorf("compound phrase cannot start with '%s'", lex.token)
 	}
@@ -906,7 +906,7 @@ func getCompoundPhrase(lex *lexer, allowColon bool) (string, error) {
 
 func getCompoundSuffix(lex *lexer, allowColon bool) string {
 	s := ""
-	stopTokens := []string{"*", ",", "(", ")", "[", "]", "|", "!", ""}
+	stopTokens := []string{"*", ",", "(", ")", "[", "]", "|", ""}
 	if !allowColon {
 		stopTokens = append(stopTokens, ":")
 	}
@@ -918,7 +918,7 @@ func getCompoundSuffix(lex *lexer, allowColon bool) string {
 }
 
 func getCompoundToken(lex *lexer) (string, error) {
-	stopTokens := []string{",", "(", ")", "[", "]", "|", "!", ""}
+	stopTokens := []string{",", "(", ")", "[", "]", "|", ""}
 	if lex.isKeyword(stopTokens...) {
 		return "", fmt.Errorf("compound token cannot start with '%s'", lex.token)
 	}
diff --git a/lib/logstorage/pipe.go b/lib/logstorage/pipe.go
index 6279d98de..5b0bc8b46 100644
--- a/lib/logstorage/pipe.go
+++ b/lib/logstorage/pipe.go
@@ -213,7 +213,7 @@ func parsePipe(lex *lexer) (pipe, error) {
 			return nil, fmt.Errorf("cannot parse 'replace_regexp' pipe: %w", err)
 		}
 		return pr, nil
-	case lex.isKeyword("sort"):
+	case lex.isKeyword("sort"), lex.isKeyword("order"):
 		ps, err := parsePipeSort(lex)
 		if err != nil {
 			return nil, fmt.Errorf("cannot parse 'sort' pipe: %w", err)
@@ -309,7 +309,7 @@ var pipeNames = func() map[string]struct{} {
 		"rename", "mv",
 		"replace",
 		"replace_regexp",
-		"sort",
+		"sort", "order",
 		"stats",
 		"stream_context",
 		"top",
diff --git a/lib/logstorage/pipe_sort.go b/lib/logstorage/pipe_sort.go
index caebb08b6..cffb12c56 100644
--- a/lib/logstorage/pipe_sort.go
+++ b/lib/logstorage/pipe_sort.go
@@ -116,11 +116,9 @@ func newPipeSortProcessor(ps *pipeSort, workersCount int, stopCh <-chan struct{}
 	for i := range shards {
 		shards[i] = pipeSortProcessorShard{
 			pipeSortProcessorShardNopad: pipeSortProcessorShardNopad{
-				ps:              ps,
-				stateSizeBudget: stateSizeBudgetChunk,
+				ps: ps,
 			},
 		}
-		maxStateSize -= stateSizeBudgetChunk
 	}
 
 	psp := &pipeSortProcessor{
@@ -748,8 +746,8 @@ func sortBlockLess(shardA *pipeSortProcessorShard, rowIdxA int, shardB *pipeSort
 }
 
 func parsePipeSort(lex *lexer) (*pipeSort, error) {
-	if !lex.isKeyword("sort") {
-		return nil, fmt.Errorf("expecting 'sort'; got %q", lex.token)
+	if !lex.isKeyword("sort") && !lex.isKeyword("order") {
+		return nil, fmt.Errorf("expecting 'sort' or 'order'; got %q", lex.token)
 	}
 	lex.nextToken()
 
diff --git a/lib/logstorage/pipe_sort_topk.go b/lib/logstorage/pipe_sort_topk.go
index 5a25b3444..ccccd6e0f 100644
--- a/lib/logstorage/pipe_sort_topk.go
+++ b/lib/logstorage/pipe_sort_topk.go
@@ -20,11 +20,9 @@ func newPipeTopkProcessor(ps *pipeSort, workersCount int, stopCh <-chan struct{}
 	for i := range shards {
 		shards[i] = pipeTopkProcessorShard{
 			pipeTopkProcessorShardNopad: pipeTopkProcessorShardNopad{
-				ps:              ps,
-				stateSizeBudget: stateSizeBudgetChunk,
+				ps: ps,
 			},
 		}
-		maxStateSize -= stateSizeBudgetChunk
 	}
 
 	ptp := &pipeTopkProcessor{
diff --git a/lib/logstorage/pipe_stats.go b/lib/logstorage/pipe_stats.go
index 9d1906fd3..0f44f2403 100644
--- a/lib/logstorage/pipe_stats.go
+++ b/lib/logstorage/pipe_stats.go
@@ -162,11 +162,8 @@ func (ps *pipeStats) newPipeProcessor(workersCount int, stopCh <-chan struct{},
 		shards[i] = pipeStatsProcessorShard{
 			pipeStatsProcessorShardNopad: pipeStatsProcessorShardNopad{
 				ps: ps,
-
-				stateSizeBudget: stateSizeBudgetChunk,
 			},
 		}
-		maxStateSize -= stateSizeBudgetChunk
 	}
 
 	psp := &pipeStatsProcessor{
@@ -577,6 +574,9 @@ func parsePipeStats(lex *lexer, needStatsKeyword bool) (*pipeStats, error) {
 		resultName := ""
 		if lex.isKeyword(",", "|", ")", "") {
 			resultName = sf.String()
+			if f.iff != nil {
+				resultName += " " + f.iff.String()
+			}
 		} else {
 			if lex.isKeyword("as") {
 				lex.nextToken()
diff --git a/lib/logstorage/pipe_stream_context.go b/lib/logstorage/pipe_stream_context.go
index 06a86c39d..09400bdf5 100644
--- a/lib/logstorage/pipe_stream_context.go
+++ b/lib/logstorage/pipe_stream_context.go
@@ -74,11 +74,9 @@ func (pc *pipeStreamContext) newPipeProcessor(workersCount int, stopCh <-chan st
 	for i := range shards {
 		shards[i] = pipeStreamContextProcessorShard{
 			pipeStreamContextProcessorShardNopad: pipeStreamContextProcessorShardNopad{
-				pc:              pc,
-				stateSizeBudget: stateSizeBudgetChunk,
+				pc: pc,
 			},
 		}
-		maxStateSize -= stateSizeBudgetChunk
 	}
 
 	pcp := &pipeStreamContextProcessor{
diff --git a/lib/logstorage/pipe_top.go b/lib/logstorage/pipe_top.go
index 6230ad161..034038b0a 100644
--- a/lib/logstorage/pipe_top.go
+++ b/lib/logstorage/pipe_top.go
@@ -79,11 +79,9 @@ func (pt *pipeTop) newPipeProcessor(workersCount int, stopCh <-chan struct{}, ca
 	for i := range shards {
 		shards[i] = pipeTopProcessorShard{
 			pipeTopProcessorShardNopad: pipeTopProcessorShardNopad{
-				pt:              pt,
-				stateSizeBudget: stateSizeBudgetChunk,
+				pt: pt,
 			},
 		}
-		maxStateSize -= stateSizeBudgetChunk
 	}
 
 	ptp := &pipeTopProcessor{
@@ -168,6 +166,7 @@ func (shard *pipeTopProcessorShard) writeBlock(br *blockResult) {
 		if c.valueType == valueTypeDict {
 			a := encoding.GetUint64s(len(c.dictValues))
 			hits := a.A
+			clear(hits)
 			valuesEncoded := c.getValuesEncoded(br)
 			for _, v := range valuesEncoded {
 				idx := unmarshalUint8(v)
diff --git a/lib/logstorage/pipe_uniq.go b/lib/logstorage/pipe_uniq.go
index ef1b2985f..c33cfc7f0 100644
--- a/lib/logstorage/pipe_uniq.go
+++ b/lib/logstorage/pipe_uniq.go
@@ -74,11 +74,9 @@ func (pu *pipeUniq) newPipeProcessor(workersCount int, stopCh <-chan struct{}, c
 	for i := range shards {
 		shards[i] = pipeUniqProcessorShard{
 			pipeUniqProcessorShardNopad: pipeUniqProcessorShardNopad{
-				pu:              pu,
-				stateSizeBudget: stateSizeBudgetChunk,
+				pu: pu,
 			},
 		}
-		maxStateSize -= stateSizeBudgetChunk
 	}
 
 	pup := &pipeUniqProcessor{
@@ -137,7 +135,7 @@ type pipeUniqProcessorShardNopad struct {
 //
 // It returns false if the block cannot be written because of the exceeded limit.
 func (shard *pipeUniqProcessorShard) writeBlock(br *blockResult) bool {
-	if limit := shard.pu.limit; limit > 0 && uint64(len(shard.m)) >= limit {
+	if limit := shard.pu.limit; limit > 0 && uint64(len(shard.m)) > limit {
 		return false
 	}
 
@@ -171,6 +169,7 @@ func (shard *pipeUniqProcessorShard) writeBlock(br *blockResult) bool {
 			if needHits {
 				a := encoding.GetUint64s(len(c.dictValues))
 				hits := a.A
+				clear(hits)
 				valuesEncoded := c.getValuesEncoded(br)
 				for _, v := range valuesEncoded {
 					idx := unmarshalUint8(v)
@@ -302,7 +301,7 @@ func (pup *pipeUniqProcessor) flush() error {
 
 	// There is little sense in returning partial hits when the limit on the number of unique entries is reached.
 	// It is better from UX experience is to return zero hits instead.
-	resetHits := pup.pu.limit > 0 && uint64(len(m)) >= pup.pu.limit
+	resetHits := pup.pu.limit > 0 && uint64(len(m)) > pup.pu.limit
 
 	// write result
 	wctx := &pipeUniqWriteContext{
diff --git a/lib/logstorage/stats_count_uniq.go b/lib/logstorage/stats_count_uniq.go
index b7aa87e4e..42a71a03f 100644
--- a/lib/logstorage/stats_count_uniq.go
+++ b/lib/logstorage/stats_count_uniq.go
@@ -355,7 +355,7 @@ func (sup *statsCountUniqProcessor) updateState(v []byte) int {
 
 func (sup *statsCountUniqProcessor) limitReached() bool {
 	limit := sup.su.limit
-	return limit > 0 && uint64(len(sup.m)) >= limit
+	return limit > 0 && uint64(len(sup.m)) > limit
 }
 
 func parseStatsCountUniq(lex *lexer) (*statsCountUniq, error) {
diff --git a/lib/logstorage/stats_uniq_values.go b/lib/logstorage/stats_uniq_values.go
index a266b2c02..25417efc9 100644
--- a/lib/logstorage/stats_uniq_values.go
+++ b/lib/logstorage/stats_uniq_values.go
@@ -215,7 +215,7 @@ func (sup *statsUniqValuesProcessor) updateState(v string) int {
 
 func (sup *statsUniqValuesProcessor) limitReached() bool {
 	limit := sup.su.limit
-	return limit > 0 && uint64(len(sup.m)) >= limit
+	return limit > 0 && uint64(len(sup.m)) > limit
 }
 
 func marshalJSONArray(items []string) string {
diff --git a/lib/logstorage/stats_values.go b/lib/logstorage/stats_values.go
index aab5475d5..eb9c100de 100644
--- a/lib/logstorage/stats_values.go
+++ b/lib/logstorage/stats_values.go
@@ -184,7 +184,7 @@ func (svp *statsValuesProcessor) finalizeStats() string {
 
 func (svp *statsValuesProcessor) limitReached() bool {
 	limit := svp.sv.limit
-	return limit > 0 && uint64(len(svp.values)) >= limit
+	return limit > 0 && uint64(len(svp.values)) > limit
 }
 
 func parseStatsValues(lex *lexer) (*statsValues, error) {


Test patch:
diff --git a/app/vlinsert/elasticsearch/elasticsearch_test.go b/app/vlinsert/elasticsearch/elasticsearch_test.go
index ca88d2ccc..bfb1cd52e 100644
--- a/app/vlinsert/elasticsearch/elasticsearch_test.go
+++ b/app/vlinsert/elasticsearch/elasticsearch_test.go
@@ -78,15 +78,18 @@ func TestReadBulkRequest_Success(t *testing.T) {
 {"create":{"_index":"filebeat-8.8.0"}}
 {"@timestamp":"2023-06-06 04:48:12.735+01:00","message":"baz"}
 {"index":{"_index":"filebeat-8.8.0"}}
-{"message":"xyz","@timestamp":"2023-06-06T04:48:13.735Z","x":"y"}
+{"message":"xyz","@timestamp":"1686026893735","x":"y"}
+{"create":{"_index":"filebeat-8.8.0"}}
+{"message":"qwe rty","@timestamp":"1686026893"}
 `
 	timeField := "@timestamp"
 	msgField := "message"
-	rowsExpected := 3
-	timestampsExpected := []int64{1686026891735000000, 1686023292735000000, 1686026893735000000}
+	rowsExpected := 4
+	timestampsExpected := []int64{1686026891735000000, 1686023292735000000, 1686026893735000000, 1686026893000000000}
 	resultExpected := `{"@timestamp":"","log.offset":"71770","log.file.path":"/var/log/auth.log","_msg":"foobar"}
 {"@timestamp":"","_msg":"baz"}
-{"_msg":"xyz","@timestamp":"","x":"y"}`
+{"_msg":"xyz","@timestamp":"","x":"y"}
+{"_msg":"qwe rty","@timestamp":""}`
 	f(data, timeField, msgField, rowsExpected, timestampsExpected, resultExpected)
 }
 
diff --git a/app/vlinsert/insertutils/timestamp_test.go b/app/vlinsert/insertutils/timestamp_test.go
index a386f09fa..a7f935384 100644
--- a/app/vlinsert/insertutils/timestamp_test.go
+++ b/app/vlinsert/insertutils/timestamp_test.go
@@ -27,25 +27,41 @@ func TestExtractTimestampRFC3339NanoFromFields_Success(t *testing.T) {
 		}
 	}
 
+	// UTC time
 	f("time", []logstorage.Field{
 		{Name: "foo", Value: "bar"},
 		{Name: "time", Value: "2024-06-18T23:37:20Z"},
 	}, 1718753840000000000)
 
+	// Time with timezone
 	f("time", []logstorage.Field{
 		{Name: "foo", Value: "bar"},
 		{Name: "time", Value: "2024-06-18T23:37:20+08:00"},
 	}, 1718725040000000000)
 
+	// SQL datetime format
 	f("time", []logstorage.Field{
 		{Name: "foo", Value: "bar"},
-		{Name: "time", Value: "2024-06-18T23:37:20.123-05:30"},
+		{Name: "time", Value: "2024-06-18 23:37:20.123-05:30"},
 	}, 1718773640123000000)
 
+	// Time with nanosecond precision
 	f("time", []logstorage.Field{
 		{Name: "time", Value: "2024-06-18T23:37:20.123456789-05:30"},
 		{Name: "foo", Value: "bar"},
 	}, 1718773640123456789)
+
+	// Unix timestamp in milliseconds
+	f("time", []logstorage.Field{
+		{Name: "foo", Value: "bar"},
+		{Name: "time", Value: "1718773640123"},
+	}, 1718773640123000000)
+
+	// Unix timestamp in seconds
+	f("time", []logstorage.Field{
+		{Name: "foo", Value: "bar"},
+		{Name: "time", Value: "1718773640"},
+	}, 1718773640000000000)
 }
 
 func TestExtractTimestampRFC3339NanoFromFields_Error(t *testing.T) {
diff --git a/lib/flagutil/password_test.go b/lib/flagutil/password_test.go
index e7a03c2a1..8a9583406 100644
--- a/lib/flagutil/password_test.go
+++ b/lib/flagutil/password_test.go
@@ -32,7 +32,7 @@ func TestPassword(t *testing.T) {
 
 	// read the password from file by relative path
 	localPassFile := "testdata/password.txt"
-	expectedPassword = "foo-bar-baz\n\n\n"
+	expectedPassword = "foo-bar-baz"
 	path := "file://" + localPassFile
 	if err := p.Set(path); err != nil {
 		t.Fatalf("cannot set password to file: %s", err)
@@ -52,7 +52,7 @@ func TestPassword(t *testing.T) {
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
-	expectedPassword = "foo-bar-baz\n\n\n"
+	expectedPassword = "foo-bar-baz"
 	path = "file://" + localPassFile
 	if err := p.Set(path); err != nil {
 		t.Fatalf("unexpected error: %s", err)
diff --git a/lib/logstorage/parser_test.go b/lib/logstorage/parser_test.go
index 84093adb7..853f380c7 100644
--- a/lib/logstorage/parser_test.go
+++ b/lib/logstorage/parser_test.go
@@ -646,6 +646,8 @@ func TestParseQuerySuccess(t *testing.T) {
 	f(`not(foo)`, `!foo`)
 	f(`not (foo)`, `!foo`)
 	f(`not ( foo or bar )`, `!(foo or bar)`)
+	f(`!(foo or bar)`, `!(foo or bar)`)
+	f(`-(foo or bar)`, `!(foo or bar)`)
 	f(`foo:!""`, `!foo:""`)
 	f("_msg:foo", "foo")
 	f("'foo:bar'", `"foo:bar"`)
@@ -944,8 +946,8 @@ func TestParseQuerySuccess(t *testing.T) {
 	f("foo-bar+baz*", `"foo-bar+baz"*`)
 	f("foo- bar", `"foo-" bar`)
 	f("foo -bar", `foo !bar`)
-	f("foo!bar", `foo !bar`)
-	f("foo:aa!bb:cc", `foo:aa !bb:cc`)
+	f("foo!bar", `"foo!bar"`)
+	f("foo:aa!bb:cc", `foo:"aa!bb:cc"`)
 	f(`foo:bar:baz`, `foo:"bar:baz"`)
 	f(`foo:(bar baz:xxx)`, `foo:bar foo:"baz:xxx"`)
 	f(`foo:(_time:abc or not z)`, `foo:"_time:abc" or !foo:z`)
@@ -1025,6 +1027,7 @@ func TestParseQuerySuccess(t *testing.T) {
 	f(`* | stats count('') foo`, `* | stats count(_msg) as foo`)
 	f(`* | stats count(foo) ''`, `* | stats count(foo) as _msg`)
 	f(`* | count()`, `* | stats count(*) as "count(*)"`)
+	f(`* | count(), count() if (foo)`, `* | stats count(*) as "count(*)", count(*) if (foo) as "count(*) if (foo)"`)
 
 	// stats pipe count_empty
 	f(`* | stats count_empty() x`, `* | stats count_empty(*) as x`)
@@ -1150,9 +1153,11 @@ func TestParseQuerySuccess(t *testing.T) {
 
 	// sort pipe
 	f(`* | sort`, `* | sort`)
+	f(`* | order`, `* | sort`)
 	f(`* | sort desc`, `* | sort desc`)
 	f(`* | sort by()`, `* | sort`)
 	f(`* | sort bY (foo)`, `* | sort by (foo)`)
+	f(`* | ORDer bY (foo)`, `* | sort by (foo)`)
 	f(`* | sORt bY (_time, _stream DEsc, host)`, `* | sort by (_time, _stream desc, host)`)
 	f(`* | sort bY (foo desc, bar,) desc`, `* | sort by (foo desc, bar) desc`)
 	f(`* | sort limit 10`, `* | sort limit 10`)
diff --git a/lib/logstorage/pipe_sort_test.go b/lib/logstorage/pipe_sort_test.go
index 671f4b0e7..0385a51c0 100644
--- a/lib/logstorage/pipe_sort_test.go
+++ b/lib/logstorage/pipe_sort_test.go
@@ -308,7 +308,7 @@ func TestPipeSort(t *testing.T) {
 	})
 
 	// Sort by multiple fields with offset and limit
-	f("sort by (a, b) desc offset 2 limit 100", [][]Field{
+	f("order by (a, b) desc offset 2 limit 100", [][]Field{
 		{
 			{"_msg", `abc`},
 			{"a", `2`},
@@ -360,5 +360,5 @@ func TestPipeSortUpdateNeededFields(t *testing.T) {
 
 	// needed fields intersect with src
 	f("sort by(s1,s2)", "s1,f1,f2", "", "s1,s2,f1,f2", "")
-	f("sort by(s1,s2) rank as x", "s1,f1,f2,x", "", "s1,s2,f1,f2", "")
+	f("order by(s1,s2) rank as x", "s1,f1,f2,x", "", "s1,s2,f1,f2", "")
 }
diff --git a/lib/logstorage/pipe_uniq_test.go b/lib/logstorage/pipe_uniq_test.go
index 3c1cb7372..f3f61effd 100644
--- a/lib/logstorage/pipe_uniq_test.go
+++ b/lib/logstorage/pipe_uniq_test.go
@@ -114,13 +114,41 @@ func TestPipeUniq(t *testing.T) {
 		{
 			{"a", "2"},
 			{"b", "3"},
-			{"hits", "0"},
+			{"hits", "2"},
 		},
 		{
 			{"a", `2`},
 			{"b", `54`},
 			{"c", "d"},
-			{"hits", "0"},
+			{"hits", "1"},
+		},
+	})
+
+	f("uniq hits limit 3", [][]Field{
+		{
+			{"a", `2`},
+			{"b", `3`},
+		},
+		{
+			{"a", "2"},
+			{"b", "3"},
+		},
+		{
+			{"a", `2`},
+			{"b", `54`},
+			{"c", "d"},
+		},
+	}, [][]Field{
+		{
+			{"a", "2"},
+			{"b", "3"},
+			{"hits", "2"},
+		},
+		{
+			{"a", `2`},
+			{"b", `54`},
+			{"c", "d"},
+			{"hits", "1"},
 		},
 	})
 
diff --git a/lib/logstorage/storage_search_test.go b/lib/logstorage/storage_search_test.go
index 4fd7ed0ac..35530309e 100644
--- a/lib/logstorage/storage_search_test.go
+++ b/lib/logstorage/storage_search_test.go
@@ -384,9 +384,9 @@ func TestStorageRunQuery(t *testing.T) {
 		}
 
 		resultsExpected := []ValueWithHits{
-			{`{instance="host-0:234",job="foobar"}`, 0},
-			{`{instance="host-1:234",job="foobar"}`, 0},
-			{`{instance="host-2:234",job="foobar"}`, 0},
+			{`{instance="host-0:234",job="foobar"}`, 385},
+			{`{instance="host-1:234",job="foobar"}`, 385},
+			{`{instance="host-2:234",job="foobar"}`, 385},
 		}
 		if !reflect.DeepEqual(results, resultsExpected) {
 			t.Fatalf("unexpected result; got\n%v\nwant\n%v", results, resultsExpected)